【问题标题】:Merge two data frames while using boolean indices (to filter)使用布尔索引合并两个数据帧(过滤)
【发布时间】:2016-07-25 19:08:23
【问题描述】:

我有一个与语法相关的简单问题,但无法弄清楚。

我有两个数据框 df1 和 df2,我希望 a) 在特定列上合并,而 b) 同时检查每个数据框中的另一列是否存在布尔关系(>、

关键部分是我需要同时执行 a 和 b,因为数据帧非常大。在一个步骤中简单地合并两个数据帧,然后在第二步中删除不通过布尔逻辑的行是行不通的。这是因为合并后的数据帧会非常非常大,导致我两个内存不足。

所以,我有:

df1:
    Col_1   Col_2   Test_Value
0   A       B       1
1   B       A       3
2   A       B       2
3   B       A       5
4   A       B       2
5   B       A       1

df2:
    Col_1   Col_2   Test_Value
0   A       B       1
1   B       A       3
2   A       B       2
3   B       A       5
4   A       B       2
5   B       A       1

(为简单起见,两个数据框完全相同)

我想合并它们,像这样:

df3 = pd.merge(df1, df2, left_on=['Col_1'], right_on=['Col_2'])

同时过滤 df1['Test Value'] 小于 df2['Test Value'] 的任何行,如下所示:

df3.loc[df3['Test_Value_x'] < df3['Test_Value_y']]

结果是:

    Col_1_x Col_2_x Test_Value_x    Col_1_y Col_2_y Test_Value_y
0   A       B       1               B       A       3
1   A       B       1               B       A       5
3   A       B       2               B       A       3
4   A       B       2               B       A       5
6   A       B       2               B       A       3
7   A       B       2               B       A       5
16  B       A       1               A       B       2
17  B       A       1               A       B       2

同样,我可以使用上面的代码分两步执行此操作,但它会给我带来内存问题,因为中间数据帧会很大。

那么有没有可以结合这个的语法,

df3 = pd.merge(df1, df2, left_on=['Col_1'], right_on=['Col_2'])

有了这个,

df3.loc[df3['Test_Value_x'] < df3['Test_Value_y']]

【问题讨论】:

    标签: python pandas merge boolean


    【解决方案1】:

    试试这个:

    import pandas as pd
    
    df1_col1 = pd.Series(['A', 'B', 'A', 'B', 'A', 'B'], index=[0, 1, 2, 3, 4, 5 ])
    df1_col2 = pd.Series(['B', 'A', 'B', 'A', 'B', 'A'], index=[0, 1, 2, 3, 4, 5])
    df1_col3 = pd.Series([1, 3, 2, 5, 2, 1], index=[0, 1, 2, 3, 4, 5])
    df1 = pd.concat([df1_col1, df1_col2, df1_col3], axis=1)
    
    df1 = df1.rename(columns={0: 'Col_1', 1: 'Col_2', 2: 'Test_Value'})
    df2 = df1.copy(deep=True)
    

    如上回答您的问题:

    df3 = pd.merge(df1, df2, left_on=['Col_1'], right_on=['Col_2'])[pd.merge(df1, df2, left_on=['Col_1'], right_on=['Col_2'])['Test_Value_x']
          <pd.merge(df1, df2, left_on=['Col_1'], right_on=['Col_2'])['Test_Value_y']]
    

    【讨论】:

    • 我不确定这是否会扩展到您拥有的数据集,但有兴趣知道结果:-)
    • 有趣。这绝对适用于我发布的示例数据。我将很快大规模尝试并发布结果。您能解释一下您的解决方案中发生了什么吗?看起来它正在代码的第一部分进行合并,然后再进行两次合并,以测试不等式(小于)。我描述的对吗?
    • 我的答案基于布尔索引部分here 如果您仍然不明白,我可以尝试更好地解释。
    • 我对此很陌生,所以任何额外的解释都会有所帮助。我认为它分为两块。第一个是做合并,第二个是做布尔索引? (另外,你怎么称呼代码块?子句?)Chunk 1 --&gt; df3 = pd.merge(df1, df2, left_on=['Col_1'], right_on=['Col_2']) Chunk 2 --&gt; [pd.merge(df1, df2, left_on=['Col_1'], right_on=['Col_2'])['Test_Value_x'] &lt;pd.merge(df1, df2, left_on=['Col_1'], right_on=['Col_2'])['Test_Value_y']]
    • 正如你所描述的,第一个块是合并的数据帧。 pd.merge(df1, df2, left_on=['Col_1'], right_on=['Col_2']) 包裹在[] 中的第二个块相当于where 子句,因此pd.merge(df1, df2, left_on=['Col_1'], right_on=['Col_2'])['Test_Value_x'] 正在选择一个特定字段并将其与&lt; 另一个字段pd.merge(df1, df2, left_on=['Col_1'], right_on=['Col_2'])['Test_Value_y'] 进行比较
    猜你喜欢
    • 1970-01-01
    • 2019-08-11
    • 2021-08-01
    • 2022-07-20
    • 2021-03-31
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    • 2021-07-10
    相关资源
    最近更新 更多