我想将九个Pandas数据帧合并到一个数据帧中,在两列上进行连接,控制列名。这可能吗?
我有九个数据集。所有这些都有以下列:
org, name, items,spend
我想将它们加入到包含以下列的单个数据框中:
org, name, items_df1, spend_df1, items_df2, spend_df2, items_df3...
我一直在阅读merging and joining上的文档。我现在可以合并两个数据集,如下所示:
ad = pd.DataFrame.merge(df_presents, df_trees,
on=['practice', 'name'],
suffixes=['_presents', '_trees'])
这很有效,print list(aggregate_data.columns.values)
向我展示了以下列:
[org', u'name', u'spend_presents', u'items_presents', u'spend_trees', u'items_trees'...]
但是如何才能为九列做到这一点? merge
似乎一次只能接受两个,如果按顺序执行,我的列名最终会变得非常混乱。
答案 0 :(得分:6)
您可以使用functools.reduce
以迭代方式将pd.merge
应用于每个DataFrame:
result = functools.reduce(merge, dfs)
这相当于
result = dfs[0]
for df in dfs[1:]:
result = merge(result, df)
要传递on=['org', 'name']
参数,可以使用functools.partial
定义合并函数:
merge = functools.partial(pd.merge, on=['org', 'name'])
由于在suffixes
中指定functools.partial
参数只允许
一个固定的后缀选择,因为在这里我们需要一个不同的后缀
pd.merge
调用,我认为准备DataFrames列最容易
在致电pd.merge
之前的姓名:
for i, df in enumerate(dfs, start=1):
df.rename(columns={col:'{}_df{}'.format(col, i) for col in ('items', 'spend')},
inplace=True)
例如,
import pandas as pd
import numpy as np
import functools
np.random.seed(2015)
N = 50
dfs = [pd.DataFrame(np.random.randint(5, size=(N,4)),
columns=['org', 'name', 'items', 'spend']) for i in range(9)]
for i, df in enumerate(dfs, start=1):
df.rename(columns={col:'{}_df{}'.format(col, i) for col in ('items', 'spend')},
inplace=True)
merge = functools.partial(pd.merge, on=['org', 'name'])
result = functools.reduce(merge, dfs)
print(result.head())
产量
org name items_df1 spend_df1 items_df2 spend_df2 items_df3 \
0 2 4 4 2 3 0 1
1 2 4 4 2 3 0 1
2 2 4 4 2 3 0 1
3 2 4 4 2 3 0 1
4 2 4 4 2 3 0 1
spend_df3 items_df4 spend_df4 items_df5 spend_df5 items_df6 \
0 3 1 0 1 0 4
1 3 1 0 1 0 4
2 3 1 0 1 0 4
3 3 1 0 1 0 4
4 3 1 0 1 0 4
spend_df6 items_df7 spend_df7 items_df8 spend_df8 items_df9 spend_df9
0 3 4 1 3 0 1 2
1 3 4 1 3 0 0 3
2 3 4 1 3 0 0 0
3 3 3 1 3 0 1 2
4 3 3 1 3 0 0 3
答案 1 :(得分:0)
做一个大pd.concat()
然后重命名所有列对你有用吗?类似的东西:
desired_columns = ['items', 'spend']
big_df = pd.concat([df1, df2[desired_columns], ..., dfN[desired_columns]], axis=1)
new_columns = ['org', 'name']
for i in range(num_dataframes):
new_columns.extend(['spend_df%i' % i, 'items_df%i' % i])
bid_df.columns = new_columns
这应该为您提供如下列:
org, name, spend_df0, items_df0, spend_df1, items_df1, ..., spend_df8, items_df8
答案 2 :(得分:0)
我有时也想要这个,但却无法找到内置的熊猫方式。这是我的建议(以及我下次需要时的计划):
merge_dict
。sorted(merge_dict)
。index=sorted(merge_dict)
创建一个新数据框,并在上一步中创建列。基本上,这有点像SQL中的散列连接。似乎是我能想到的最有效的方式,不应该花太长时间来编写代码。
祝你好运。