Decir que tengo la siguiente trama de datos (una columna de enteros y una columna con una lista de números enteros) ...
ID Found_IDs
0 12345 [15443, 15533, 3433]
1 15533 [2234, 16608, 12002, 7654]
2 6789 [43322, 876544, 36789]
Y también una lista separada de los ID ...
bad_ids = [15533, 876544, 36789, 11111]
Teniendo en cuenta que, y haciendo caso omiso de la df['ID']
columna y cualquier índice, quiero ver si alguno de los identificadores en la bad_ids
lista se mencionan en la df['Found_IDs']
columna. El código que tengo hasta ahora es:
df['bad_id'] = [c in l for c, l in zip(bad_ids, df['Found_IDs'])]
Esto funciona, pero sólo si la bad_ids
lista es más larga que la trama de datos y para el conjunto de datos reales de la bad_ids
lista va a ser mucho más corta que la trama de datos. Si fijo la bad_ids
lista a sólo dos elementos ...
bad_ids = [15533, 876544]
Me sale un error muy popular (He leído muchas preguntas con el mismo error) ...
ValueError: Length of values does not match length of index
He tratado de convertir la lista de una serie (sin cambio en el error). También he intentado añadir la nueva columna y fijar todos los valores que False
antes de hacer la línea de comprensión (de nuevo sin cambio en el error).
Dos preguntas:
- ¿Cómo consigo mi código (abajo) para el trabajo de una lista que es más corta que una trama de datos?
- ¿Cómo puedo obtener el código para escribir el ID real encontró de nuevo a la
df['bad_id']
columna (más útil que el Verdadero / Falso)?
Espera que la producción de bad_ids = [15533, 876544]
:
ID Found_IDs bad_id
0 12345 [15443, 15533, 3433] True
1 15533 [2234, 16608, 12002, 7654] False
2 6789 [43322, 876544, 36789] True
Ideal para la producción bad_ids = [15533, 876544]
(ID (s) se escriben en una nueva columna o columnas):
ID Found_IDs bad_id
0 12345 [15443, 15533, 3433] 15533
1 15533 [2234, 16608, 12002, 7654] False
2 6789 [43322, 876544, 36789] 876544
Código:
import pandas as pd
result_list = [[12345,[15443,15533,3433]],
[15533,[2234,16608,12002,7654]],
[6789,[43322,876544,36789]]]
df = pd.DataFrame(result_list,columns=['ID','Found_IDs'])
# works if list has four elements
# bad_ids = [15533, 876544, 36789, 11111]
# fails if list has two elements (less elements than the dataframe)
# ValueError: Length of values does not match length of index
bad_ids = [15533, 876544]
# coverting to Series doesn't change things
# bad_ids = pd.Series(bad_ids)
# print(type(bad_ids))
# setting up a new column of false values doesn't change things
# df['bad_id'] = False
print(df)
df['bad_id'] = [c in l for c, l in zip(bad_ids, df['Found_IDs'])]
print(bad_ids)
print(df)
Utilizando np.intersect1d
para obtener el Intersect de las dos listas:
df['bad_id'] = df['Found_IDs'].apply(lambda x: np.intersect1d(x, bad_ids))
ID Found_IDs bad_id
0 12345 [15443, 15533, 3433] [15533]
1 15533 [2234, 16608, 12002, 7654] []
2 6789 [43322, 876544, 36789] [876544]
O simplemente con el pitón de vainilla utilizando intersecan de sets
:
bad_ids_set = set(bad_ids)
df['Found_IDs'].apply(lambda x: list(set(x) & bad_ids_set))