Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python `pd.concat`with`join==';内部';`不';t生成数据帧的交集_Python_Python 3.x_Pandas_Dataframe_Set Intersection - Fatal编程技术网

Python `pd.concat`with`join==';内部';`不';t生成数据帧的交集

Python `pd.concat`with`join==';内部';`不';t生成数据帧的交集,python,python-3.x,pandas,dataframe,set-intersection,Python,Python 3.x,Pandas,Dataframe,Set Intersection,我正在尝试使用pd.concat从几个数据帧中提取公共行: >>> import numpy as np >>> import pandas as pd >>> x = np.random.random(size=(5, 3)) >>> df1 = pd.DataFrame(x) >>> df2 = pd.DataFrame(x[1:3]) >>> df3 = pd.DataFrame(x

我正在尝试使用pd.concat从几个数据帧中提取公共行:

>>> import numpy as np
>>> import pandas as pd
>>> x = np.random.random(size=(5, 3))
>>> df1 = pd.DataFrame(x)
>>> df2 = pd.DataFrame(x[1:3])
>>> df3 = pd.DataFrame(x[2:4])
>>> df1
          0         1         2
0  0.257662  0.453542  0.805230
1  0.060493  0.463148  0.715994
2  0.452379  0.470137  0.965709
3  0.447546  0.964252  0.163247
4  0.187212  0.973557  0.871090
>>> df2
          0         1         2
0  0.060493  0.463148  0.715994
1  0.452379  0.470137  0.965709
>>> df3
          0         1         2
0  0.452379  0.470137  0.965709
1  0.447546  0.964252  0.163247
如您所见,只有行
0.452379 0.470137 0.965709
是所有三个数据帧的公用行。为了提取它,我尝试:

>>> pd.concat([df1, df2, df3], join='inner')
          0         1         2
0  0.257662  0.453542  0.805230
1  0.060493  0.463148  0.715994
2  0.452379  0.470137  0.965709
3  0.447546  0.964252  0.163247
4  0.187212  0.973557  0.871090
0  0.060493  0.463148  0.715994
1  0.452379  0.470137  0.965709
0  0.452379  0.470137  0.965709
1  0.447546  0.964252  0.163247
因此,
join==internal
似乎不起作用!我还应该指出,
ignore\u index=True
对行为没有影响。在实际Python中,建议使用
axis=1
。然而,我认为这是错误的:

>>> pd.concat([df1, df2, df3], join='inner', axis=1)
          0         1         2         0         1         2         0         1         2
0  0.257662  0.453542  0.805230  0.060493  0.463148  0.715994  0.452379  0.470137  0.965709
1  0.060493  0.463148  0.715994  0.452379  0.470137  0.965709  0.447546  0.964252  0.163247
我现在做的有什么问题吗?另外,如果这种方法不起作用,我如何从几个数据帧中提取公共行?我正在使用熊猫版本0.25.3。

试试这个

df = pd.merge(df1, df2, how='inner', on=[col1, col2, col3])

简而言之,使用
reduce(lambda left,right:pd.merge(left,right,on=cols),dfs)
, (请参见方法2-确保包括functools import reduce中的
),但请参见
pd.concat
的说明(方法1):

方法#1
concat
):我认为最具活力、最稳健的
pd.concat
方法(特别是我尝试过的
concat
方法)是使用。与下面的第二种方法相比,此解决方案的唯一主要好处是您不必使用额外的库;但是,我认为您也可以使用
merge
编写类似的代码,而无需使用其他库:

dfs = [df1, df2, df3]
cols = [*df1.columns]                              # enclosing with [*] is the same as tolist()
for df in dfs:
    df.set_index(cols, inplace=True)               # can only use inplace when looping through dfs (at least using my simpler method)
pd.concat(dfs, join='inner', axis=1).reset_index() # see below paragraph for explanation
Out[1]: 
          0         1         2
0  0.452379  0.470137  0.965709
请注意,
join='internal'
表示您是在
索引
上加入的,而不是唯一的行。另外,
join
仅在通过
axis=1
时才起作用,这就是为什么实际上什么都不发生


方法#2:():

@Anky指出,
how='internal'
merge
的默认值。这实际上是我贴出的第一个答案,但我对预期的产出感到困惑,于是转了一圈。请参阅下面最简单的答案:

from functools import reduce
dfs = [df1, df2, df3]
cols = [*df1.columns]
reduce(lambda left,right: pd.merge(left,right,on=cols), dfs)
Out[2]: 
          0         1         2
0  0.452379  0.470137  0.965709
#添加额外的标记列
df_列表=[df1、df2、df3]
对于i,枚举中的dfi(df_列表):
dfi['tag']=i+1
#合并数据帧
df=pd.concat([df1,df2,df3],ignore_index=True)
#查找重复的行
cols=df.columns[:-1].tolist()
cond=df[cols]。重复(keep=False)
obj=df[cond].groupby(cols)['tag'].agg(元组)
#滤器
条件=对象映射(len)=len(df_列表)
obj[秒]
obj
示例:

# 0         1         2       
# 0.148080  0.837398  0.565498       (1, 3)
# 0.572673  0.256735  0.620923    (1, 2, 3)
# 0.822542  0.856137  0.645639       (1, 2)
# Name: tag, dtype: object

如果试图查找公用行,请执行以下操作:

temp = pd.concat([df1, df2, df3])
temp[temp.duplicated()]

不过,我相信有一个更优雅的解决方案。

与@Ajay a所说的方式类似

import numpy as np
import pandas as pd
x = np.random.random(size=(5, 3))
df1 = pd.DataFrame(x)
df2 = pd.DataFrame(x[1:3])
df3 = pd.DataFrame(x[2:4])
那么

然后您可以使用
pd.merge
how='inner'

pd.merge(df2, df3, how='inner')
Out[25]: 
          0         1         2
0  0.972633  0.685077  0.191109
或者如果你要找的是三者的交叉点

pd.merge(pd.merge(df1,df2,how='inner'), df3, how='inner')
Out[26]: 
          0         1         2
0  0.972633  0.685077  0.191109

使用
for循环
处理
df\u列表

df_list=[df1、df2、df3]
df_交点=df1
对于df_列表[1:]中的df:
df_intersection=pd.merge(df_intersection,df,how='inner')

所需的输出是什么?@U11 Forward:一个只有公共行的数据帧。我知道这一点,但我不想要这个。为了让它工作,我必须知道我要提前合并多少帧。我想传递数据帧列表。我不能接受使用pd.merge的解决方案。我知道这很有效,但我的问题是我不知道在哪个交集上执行多少数据帧。这就是我使用pd.concat的原因,它接受数据帧列表。@也许您可以使用
for循环
来完成这项工作:
dfu list=[df1,df2,df3];df_交叉口=df1;对于df_列表中的df[1:]:df_intersection=pd.merge(df_intersection,df,how='inner')
@Ferris:谢谢!这实际上是一个聪明的解决方法。也许你应该写下这个作为答案。我可以试试这个,不过这个看起来很复杂。我的简单问题是“pd.concat为什么不加入class='inner'工作?”@Peace有两个原因。见我更新答案的第一段。我还向您展示了如何按照您的方式获得所需的输出。我想我已经提供了您正在寻找的两种优雅的方法。如果你想用concat来做,那么你必须有一个“公共”索引。节日快乐!感谢@anky提到默认设置的好处。我会更新我的答案并相信你:)我可能误解了预期的输出,但我不相信这是正确的。我认为预期的输出是一行:
0.972633 0.685077 0.191109
pd.merge(pd.merge(df1,df2,how='inner'), df3, how='inner')
Out[26]: 
          0         1         2
0  0.972633  0.685077  0.191109