specific renombrar name data columns columnas column change python pandas dataframe merge data-analysis

renombrar - Python: los pandas combinan mĂșltiples marcos de datos



rename data frame columns python (7)

Tengo diferentes marcos de datos y necesito fusionarlos en función de la columna de fecha. Si solo tuviera dos marcos de datos, podría usar df1.merge(df2, on=''date'') , para hacerlo con tres marcos de datos, uso df1.merge(df2.merge(df3, on=''date''), on=''date'') , sin embargo, se vuelve realmente complejo e ilegible hacerlo con múltiples marcos de datos.

Todos los marcos de datos tienen una columna en común: date , pero no tienen el mismo número de filas ni columnas y solo necesito esas filas en las que cada fecha es común a cada marco de datos.

Entonces, estoy tratando de escribir una función de recursión que devuelva un marco de datos con todos los datos, pero no funcionó. ¿Cómo debo combinar múltiples marcos de datos entonces?

Intenté diferentes formas y obtuve errores como out of range , keyerror 0/1/2/3 y can not merge DataFrame with instance of type <class ''NoneType''> .

Este es el guión que escribí:

dfs = [df1, df2, df3] # list of dataframes def mergefiles(dfs, countfiles, i=0): if i == (countfiles - 2): # it gets to the second to last and merges it with the last return dfm = dfs[i].merge(mergefiles(dfs[i+1], countfiles, i=i+1), on=''date'') return dfm print(mergefiles(dfs, len(dfs)))

Un ejemplo: df_1:

May 19, 2017;1,200.00;0.1% May 18, 2017;1,100.00;0.1% May 17, 2017;1,000.00;0.1% May 15, 2017;1,901.00;0.1%

df_2:

May 20, 2017;2,200.00;1000000;0.2% May 18, 2017;2,100.00;1590000;0.2% May 16, 2017;2,000.00;1230000;0.2% May 15, 2017;2,902.00;1000000;0.2%

df_3:

May 21, 2017;3,200.00;2000000;0.3% May 17, 2017;3,100.00;2590000;0.3% May 16, 2017;3,000.00;2230000;0.3% May 15, 2017;3,903.00;2000000;0.3%

Resultado de fusión esperado:

May 15, 2017; 1,901.00;0.1%; 2,902.00;1000000;0.2%; 3,903.00;2000000;0.3%


A continuación, se encuentra la forma más limpia y comprensible de fusionar múltiples marcos de datos si no se involucran consultas complejas.

Simplemente fusione con DATE como índice y fusione usando el método OUTER (para obtener todos los datos).

import pandas as pd from functools import reduce df1 = pd.read_table(''file1.csv'', sep='','') df2 = pd.read_table(''file2.csv'', sep='','') df3 = pd.read_table(''file3.csv'', sep='','')

Entonces, básicamente cargue todos los archivos que tiene como marco de datos. Luego combine los archivos usando la función de merge o reduce .

# compile the list of dataframes you want to merge data_frames = [df1, df2, df3]

puede agregar tantos marcos de datos en el código anterior. Esta es la buena parte de este método. No hay consultas complejas involucradas.

Para mantener los valores que pertenecen a la misma fecha, debe fusionarlo el DATE

df_merged = reduce(lambda left,right: pd.merge(left,right,on=[''DATE''], how=''outer''), data_frames) # if you want to fill the values that don''t exist in the lines of merged dataframe simply fill with required strings as df_merged = reduce(lambda left,right: pd.merge(left,right,on=[''DATE''], how=''outer''), data_frames).fillna(''void'')

  • Entonces, los valores de la misma fecha están en las mismas líneas.
  • Puede llenar los datos no existentes de diferentes marcos para diferentes columnas usando fillna ().

Luego, escriba los datos combinados en el archivo csv si lo desea.

pd.DataFrame.to_csv(df_merged, ''merged.txt'', sep='','', na_rep=''.'', index=False)

Esto debería darte

DATE VALUE1 VALUE2 VALUE3 ....


Gracias por su ayuda @jezrael , @zipa y @ everestial007 , ambas respuestas son lo que necesito. Si quisiera hacer un recursivo, esto también funcionaría según lo previsto:

def mergefiles(dfs=[], on=''''): """Merge a list of files based on one column""" if len(dfs) == 1: return "List only have one element." elif len(dfs) == 2: df1 = dfs[0] df2 = dfs[1] df = df1.merge(df2, on=on) return df # Merge the first and second datafranes into new dataframe df1 = dfs[0] df2 = dfs[1] df = dfs[0].merge(dfs[1], on=on) # Create new list with merged dataframe dfl = [] dfl.append(df) # Join lists dfl = dfl + dfs[2:] dfm = mergefiles(dfl, on) return dfm


Hay 2 soluciones para esto, pero devuelve todas las columnas por separado:

import functools dfs = [df1, df2, df3] df_final = functools.reduce(lambda left,right: pd.merge(left,right,on=''date''), dfs) print (df_final) date a_x b_x a_y b_y c_x a b c_y 0 May 15,2017 900.00 0.2% 1,900.00 1000000 0.2% 2,900.00 2000000 0.2% k = np.arange(len(dfs)).astype(str) df = pd.concat([x.set_index(''date'') for x in dfs], axis=1, join=''inner'', keys=k) df.columns = df.columns.map(''_''.join) print (df) 0_a 0_b 1_a 1_b 1_c 2_a 2_b 2_c date May 15,2017 900.00 0.2% 1,900.00 1000000 0.2% 2,900.00 2000000 0.2%


La respuesta de @ dannyeuu es correcta. pd.concat naturalmente hace una unión en columnas de índice, si establece la opción del eje en 1. El valor predeterminado es una unión externa, pero también puede especificar la unión interna. Aquí hay un ejemplo:

x = pd.DataFrame({''a'': [2,4,3,4,5,2,3,4,2,5], ''b'':[2,3,4,1,6,6,5,2,4,2], ''val'': [1,4,4,3,6,4,3,6,5,7], ''val2'': [2,4,1,6,4,2,8,6,3,9]}) x.set_index([''a'',''b''], inplace=True) x.sort_index(inplace=True) y = x.__deepcopy__() y.loc[(14,14),:] = [3,1] y[''other'']=range(0,11) y.sort_values(''val'', inplace=True) z = x.__deepcopy__() z.loc[(15,15),:] = [3,4] z[''another'']=range(0,22,2) z.sort_values(''val2'',inplace=True) pd.concat([x,y,z],axis=1)


Parece que los datos tienen las mismas columnas, por lo que puede:

df1 = pd.DataFrame(data1) df2 = pd.DataFrame(data2) merged_df = pd.concat([df1, df2])


Si está filtrando por fecha común, esto lo devolverá:

dfs = [df1, df2, df3] checker = dfs[-1] check = set(checker.loc[:, 0]) for df in dfs[:-1]: check = check.intersection(set(df.loc[:, 0])) print(checker[checker.loc[:, 0].isin(check)])


functools.reduce y pd.concat son buenas soluciones, pero en términos de tiempo de ejecución, pd.concat es la mejor.

from functools import reduce import pandas as pd dfs = [df1, df2, df3, ...] nan_value = 0 # solution 1 (fast) result_1 = pd.concat(dfs, join=''outer'', axis=1).fillna(nan_value) # solution 2 result_2 = reduce(lambda left,right: pd.merge(df_left, df_right, left_index=True, right_index=True, how=''outer''), dfs).fillna(nan_value)