Tengo una columna de valores, que forman parte de un marco de datos df.

Value 
6.868061881
6.5903628020000005
6.472865833999999
6.427754219
6.40081742
6.336348032
6.277545389
6.250755132

Estos valores se han reunido a partir de varios archivos CSV. Ahora estoy tratando de retroceder y encontrar el archivo CSV original que contiene los valores. Este es mi codigo. El problema es que cada fila del archivo CSV contiene entradas alfanuméricas y estoy comparando solo las numéricas (como los valores anteriores). Entonces el código no funciona.

for item in df['Value']:
    for file in dirs:
        csv_file = csv.reader(open(file))
        for row in csv_file:
            for column in row:
                if str(column) == str(item):
                    print (file)

Además, estoy tratando de optimizar los # bucles. ¿Cómo me acerco a esto?

0
srkdb 10 may. 2019 a las 20:34

3 respuestas

La mejor respuesta

Asumiendo que dirs es una lista de rutas de archivos a archivos CSV:

csv_dfs = {file: pd.read_csv(file) for file in dirs}
csv_df = pd.concat(csv_dfs)

Si solo está buscando en la columna 'Values', esto es bastante sencillo:

print csv_df[csv_df['Values'].isin(df['Values'])]

Debido a que creamos el marco de datos a partir de un diccionario de archivos, donde las claves son nombres de archivos, los valores impresos tendrán el nombre de archivo original en el índice.


En un comentario, preguntaste cómo obtener los nombres de archivo. Debido a la forma en que construimos el índice del marco de datos, lo siguiente debería funcionar para obtener una serie de nombres de archivo:

csv_df[csv_df['Values'].isin(df['Values'])].reset_index()['level_0']

Tenga en cuenta que si no está seguro de qué columna en los CSV está haciendo coincidir, puede hacer un bucle:

for col in df.columns:
    print csv_df[csv_df[col].isin(df['Values'])]
3
ASGM 10 may. 2019 a las 18:31

La E / S de archivo generalmente llevará más tiempo que el procesamiento de datos en la memoria. Por lo tanto, si desea optimizar su código, será mejor recorrer los archivos csv una vez, en lugar de cada elemento en su marco de datos. Sugiero lo siguiente:

val_list = df['Values'].values
for file in dirs:
    csv_df = pd.read_csv(file)
    df_contains = csv_df.isin(val_list)
    if np.any(df_contains.values):
        print(file)
0
Abhineet Gupta 10 may. 2019 a las 18:06

Algunas sugerencias

Asegúrese de comparar tipos similares, por ejemplo:

if str(column) == str(item):

O bien, puede verificar los tipos antes de hacer la comparación:

if all(map(type,[column,item])) and column == item: 

O bien, descargue su CSV en un DataFrame. Este enfoque reduce el número de bucles ya que no necesita iterar las filas / líneas en file, solo las columnas:

from pandas import read_csv

for item in df['Value']:
    for file in dirs:
        csv_frame = read_csv(file)
        for column in csv_frame.columns:
            if item in csv_frame[column]:
               print(file)
0
David Zemens 10 may. 2019 a las 17:51