[英]Merging multiple dataframes together that have different columns except 5
我將 1,424 個數據幀推入一個列表,如下所示:
import os
df = []
i = 0
for filename in os.listdir(output_path):
if filename.endswith(".csv"):
df.append(pd.read_csv(os.path.join(output_path, filename)))
else:
continue
我想將它們全部合並在一起。 這是我想僅使用 2 個 dfs 來模擬的示例:
df1 = pd.read_csv('../output/2009/census_data_2009_p1.csv')
df2 = pd.read_csv('../output/2009/census_data_2009_p2.csv')
df1 = df1.merge(df2, how = 'left', on = ['Location+Type', 'Year', 'state', 'Census_tract', 'County_name'])
除了 df 列表中的所有這些,我將如何做后者? 具體來說,我想使用'Location+Type', 'Year', 'state', 'Census_tract', 'County_name'
鍵對所有數據幀進行左連接
即使我有 64 GB 的 RAM,我目前也收到此錯誤。
The kernel appears to have died. It will restart automatically.
當我運行此代碼時會發生這種情況:
from functools import reduce
df_merged = reduce(lambda l, r: pd.merge(l, r,
how='left',
on=['Location+Type',
'Year',
'state',
'Census_tract',
'County_name']), dfs)
或此代碼
[
dfi.set_index(
["Location+Type", "Year", "state", "Census_tract", "County_name"], inplace=True
)
for dfi in df
]
df[0].join(df[1:], how="left")
嘗試使用 set index 和 join:
[
dfi.set_index(
["Location+Type", "Year", "state", "Census_tract", "County_name"], inplace=True
)
for dfi in df
]
df[0].join(df[1:], how="left")
首先,在第一個代碼塊中進行一些清理:
import os
dfs = []
for filename in os.listdir(output_path):
if filename.endswith(".csv"):
dfs.append(pd.read_csv(os.path.join(output_path, filename)))
要將 DataFrame 列表合並為單個 DataFrame:
pd.concat(dfs, join='inner')
join='inner'
僅選擇 DataFrame 列表中的公共列。
一個簡短的演示:
df1 = pd.DataFrame(data=[[1,2,3], [2,3,1]], columns=['a', 'b', 'c'])
a b c
0 1 2 3
1 2 3 1
df2 = pd.DataFrame(data=[[1,2,3], [2,3,1]], columns=['b', 'c', 'd'])
b c d
0 1 2 3
1 2 3 1
pd.concat([df1, df2], join='inner')
b c
0 2 3
1 3 1
0 1 2
1 2 3
請注意結果索引。 如果需要,您可以使用reset_index()
來重置索引。
我相信最干凈的選擇之一是使用reduce
映射合並操作:
from functools import reduce
df_merged = reduce(lambda l, r: pd.merge(l, r,
how='left',
on=['Location+Type',
'Year',
'state',
'Census_tract',
'County_name']), df)
然而,這假設數據幀以所需的方式排序。
執行此操作的更內存有效的方法(但可以說不太干凈)是簡單地迭代數據幀:
df_merged = df[0].copy() # we use the initial dataframe to start
del df[0]
for _ in range(len(df)):
df_merged = df_merged.merge(df[0],
how='left',
on=['Location+Type',
'Year',
'state',
'Census_tract',
'County_name'])
# this will free up the contents of the recently merged dataframe
del df[0]
# For the columns in the variable
columns = ['Location+Type', 'Year', 'state', 'Census_tract', 'County_name']
# Set the indexes in order to join by index
for my_df in df:
my_df.set_index(columns)
# Join the dataframe
res_df = df[0]
for index in range(1, len(df)):
res_df.join(df[index], how='outer')
# Or if you only want to merge
pd.concat(df, join='outer')
首先,我會使用生成器來保存您機器的內存,執行時間可能會更長,但您的機器一次只能處理一個文件
import os
import pandas as pd
def census_dataframes():
for filename in os.listdir(output_path):
if filename.endswith(".csv"):
yield pd.read_csv(os.path.join(output_path, filename))
else:
continue
dataframes = census_dataframes()
#get first dataframe from generator
df1 = next(dataframes)
for frame in dataframes:
df1 = df1.merge(frame, how = 'left', on = ['Location+Type', 'Year', 'state', 'Census_tract', 'County_name'])
如果上述方法沒有帶來結果,請檢查輸出數據幀的大小。 為了有效使用,您至少需要比數據幀所需的內存多 2 倍。
可以通過在讀取 csv 期間優化數據類型來進一步節省內存,例如
yield pd.read_csv(os.path.join(output_path, filename), dtype= {‘a’: np.float32, ‘b’: np.int32, ‘c’: ....})
如果您有經常在列中重復的文本條目(如“男人”、“女性”、“未公開”等),您可以將它們轉換為類別並節省大量內存。 但是,要在大量文件上執行此操作需要事先准備和預先定義類別。
請參閱有關“分類數據”主題的熊貓文檔
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.