n 个数据帧的行交集的并集
The union of the intersection of rows of n dataframes
假设我有 n dataframes
,在这个例子中 n = 3.
**df1**
A B C
0 True 3 21.0
1 True 1 23.0
2 False 2 25.0
3 False 4 25.5
4 False 1 25.0
5 True 0 26.0
**df2**
A B C
0 True 3 21.0
1 True 1 23.0
2 False 2 25.0
3 False 4 25.5
4 True 2 19.0
**df3**
A B C
0 True 3 21.0
1 True 2 23.0
2 False 2 25.0
3 False 1 25.0
4 False 4 25.5
5 True 0 27.50
**dfn** ...
我想要一个 dataframe
,其中包含列 C 中的值出现在每个 dataframe
dfn 中的所有行。所以这是列上 dataframes
的 intersection
的一种 union
,在本例中是 C 列。因此对于上述数据帧,具有 19.0、26.0 和 27.50 的行不'进入决赛 dataframe
即:
**Expected df**
0 True 3 21.0
1 True 1 23.0
2 False 2 25.0
3 False 4 25.5
4 False 1 25.0
0 True 3 21.0
1 True 1 23.0
2 False 2 25.0
3 False 4 25.5
0 True 3 21.0
1 True 2 23.0
2 False 2 25.0
3 False 1 25.0
4 False 4 25.5
所以一行继续到 finaldataframe
,当且仅当,C 列中的值是见于 全部 dataframes
.
可重现代码:
import pandas as pd
df1 = pd.DataFrame({'A': [True,True,False,False,False,True], 'B': [3,1,2,4,1,0],
'C': [21.0,23.0,25.0,25.5,25.0,26.0]})
df2 = pd.DataFrame({'A': [True,True,False,False,False], 'B': [3,1,2,4,2],
'C': [21.0,23.0,25.0,25.5,19.0]})
df3 = pd.DataFrame({'A': [True,True,False,False,False,True], 'B': [3,2,2,1,4,0],
'C': [21.0,23.0,25.0,25.0,25.5,27.5]})
dfn = ...
为简单起见,将数据帧存储在列表中。我们将利用集合操作来尽可能地加快速度。
df_list = [df1, df2, df3, ...]
common_idx = set.intersection(*[set(df['C']) for df in df_list])
print(common_idx)
{21.0, 23.0, 25.0, 25.5}
感谢@smci 的改进! set.intersection
将找到所有索引的交集。最后,调用pd.concat
,垂直连接数据帧,然后使用query
过滤上一步获得的公共索引。
pd.concat(df_list, ignore_index=True).query('C in @common_idx')
A B C
0 True 3 21.0
1 True 1 23.0
2 False 2 25.0
3 False 4 25.5
4 False 1 25.0
5 True 3 21.0
6 True 1 23.0
7 False 2 25.0
8 False 4 25.5
9 True 3 21.0
10 True 2 23.0
11 False 2 25.0
12 False 1 25.0
13 False 4 25.5
您可以使用 pd.concat:
# merge column C from all DataFrames
df_C = pd.concat([df1,df2,df3],1)['C']
# concat all DataFrames
df_all = pd.concat([df1,df2,df3])
# only extract rows with its C value appears in all DataFrames C columns.
df_all.loc[df_all.apply(lambda x: df_C.eq(x.C).sum().all(), axis=1)]
Out[105]:
A B C
0 True 3 21.0
1 True 1 23.0
2 False 2 25.0
3 False 4 25.5
4 False 1 25.0
0 True 3 21.0
1 True 1 23.0
2 False 2 25.0
3 False 4 25.5
0 True 3 21.0
1 True 2 23.0
2 False 2 25.0
3 False 1 25.0
4 False 4 25.5
最直接的方法似乎是计算(n 向交集)公共 C 值(作为 set/list),然后使用 .isin
:
进行过滤
common_C_values = set.intersection(set(df1['C']), set(df2['C']), set(df3['C']))
df_all = pd.concat([df1,df2,df3])
df_all = df_all[ df_all['C'].isin(common_C_values) ]
假设我有 n dataframes
,在这个例子中 n = 3.
**df1**
A B C
0 True 3 21.0
1 True 1 23.0
2 False 2 25.0
3 False 4 25.5
4 False 1 25.0
5 True 0 26.0
**df2**
A B C
0 True 3 21.0
1 True 1 23.0
2 False 2 25.0
3 False 4 25.5
4 True 2 19.0
**df3**
A B C
0 True 3 21.0
1 True 2 23.0
2 False 2 25.0
3 False 1 25.0
4 False 4 25.5
5 True 0 27.50
**dfn** ...
我想要一个 dataframe
,其中包含列 C 中的值出现在每个 dataframe
dfn 中的所有行。所以这是列上 dataframes
的 intersection
的一种 union
,在本例中是 C 列。因此对于上述数据帧,具有 19.0、26.0 和 27.50 的行不'进入决赛 dataframe
即:
**Expected df**
0 True 3 21.0
1 True 1 23.0
2 False 2 25.0
3 False 4 25.5
4 False 1 25.0
0 True 3 21.0
1 True 1 23.0
2 False 2 25.0
3 False 4 25.5
0 True 3 21.0
1 True 2 23.0
2 False 2 25.0
3 False 1 25.0
4 False 4 25.5
所以一行继续到 finaldataframe
,当且仅当,C 列中的值是见于 全部 dataframes
.
可重现代码:
import pandas as pd
df1 = pd.DataFrame({'A': [True,True,False,False,False,True], 'B': [3,1,2,4,1,0],
'C': [21.0,23.0,25.0,25.5,25.0,26.0]})
df2 = pd.DataFrame({'A': [True,True,False,False,False], 'B': [3,1,2,4,2],
'C': [21.0,23.0,25.0,25.5,19.0]})
df3 = pd.DataFrame({'A': [True,True,False,False,False,True], 'B': [3,2,2,1,4,0],
'C': [21.0,23.0,25.0,25.0,25.5,27.5]})
dfn = ...
为简单起见,将数据帧存储在列表中。我们将利用集合操作来尽可能地加快速度。
df_list = [df1, df2, df3, ...]
common_idx = set.intersection(*[set(df['C']) for df in df_list])
print(common_idx)
{21.0, 23.0, 25.0, 25.5}
感谢@smci 的改进! set.intersection
将找到所有索引的交集。最后,调用pd.concat
,垂直连接数据帧,然后使用query
过滤上一步获得的公共索引。
pd.concat(df_list, ignore_index=True).query('C in @common_idx')
A B C
0 True 3 21.0
1 True 1 23.0
2 False 2 25.0
3 False 4 25.5
4 False 1 25.0
5 True 3 21.0
6 True 1 23.0
7 False 2 25.0
8 False 4 25.5
9 True 3 21.0
10 True 2 23.0
11 False 2 25.0
12 False 1 25.0
13 False 4 25.5
您可以使用 pd.concat:
# merge column C from all DataFrames
df_C = pd.concat([df1,df2,df3],1)['C']
# concat all DataFrames
df_all = pd.concat([df1,df2,df3])
# only extract rows with its C value appears in all DataFrames C columns.
df_all.loc[df_all.apply(lambda x: df_C.eq(x.C).sum().all(), axis=1)]
Out[105]:
A B C
0 True 3 21.0
1 True 1 23.0
2 False 2 25.0
3 False 4 25.5
4 False 1 25.0
0 True 3 21.0
1 True 1 23.0
2 False 2 25.0
3 False 4 25.5
0 True 3 21.0
1 True 2 23.0
2 False 2 25.0
3 False 1 25.0
4 False 4 25.5
最直接的方法似乎是计算(n 向交集)公共 C 值(作为 set/list),然后使用 .isin
:
common_C_values = set.intersection(set(df1['C']), set(df2['C']), set(df3['C']))
df_all = pd.concat([df1,df2,df3])
df_all = df_all[ df_all['C'].isin(common_C_values) ]