【问题标题】:How to subset tuples in a pandas DataFrame, given lists of tuples?给定元组列表,如何在 pandas DataFrame 中对元组进行子集化?
【发布时间】:2020-02-25 18:44:21
【问题描述】:

我有以下熊猫数据框。有两列AB 由多个元组的列表组成。

import pandas as pd
dictionary_input = {'A' : [5,6,3,4], 
                    'B' : [[('AA', 4, 11), ('ABC', 28, 99), ('ABC', 23, 86)], [('AA', 2, 10)], [('ABC', 56, 76), ('BB', 15, 183)], [('BB', 15, 183)]], 
                    'C': [[('XYZ', 7, 9), ('XX',24, 33), ('BB', 179, 184)], [('XX',72, 75)], [('ABC',25, 45)], [('BB',91, 187)]]}

df = pd.DataFrame(dictionary_input)
print(df)

导致:

   A                                            B                                            C
0  5  [(AA, 4, 11), (ABC, 28, 99), (ABC, 23, 86)]  [(XYZ, 7, 9), (XX, 24, 33), (BB, 179, 184)]
1  6                                [(AA, 2, 10)]                               [(XX, 72, 75)]
2  3               [(ABC, 56, 76), (BB, 15, 183)]                              [(ABC, 25, 45)]
3  4                              [(BB, 15, 183)]                              [(BB, 91, 187)]

我的问题是我想根据元组列表中的值对这个 DataFrame 进行子集化,即基于单个元组。

如果我基于 B 对数据帧进行子集化,则具有元组 (BB, 15, 183),那么以下将是输出:

   A                                            B                                            C
2  3               [(ABC, 56, 76), (BB, 15, 183)]                              [(ABC, 25, 45)]
3  4                              [(BB, 15, 183)]                              [(BB, 91, 187)]

我尝试使用

来完成此操作
df[df.B.isin(('BB', 15, 183))]

但这是错误的,因为它给了我一个空的 DataFrame。

如果值是元组,我如何根据 Pandas DataFrame 中列表中的值进行子集化?

【问题讨论】:

  • 在数据框中包含元组列表也是错误的 :-)

标签: python pandas tuples subset


【解决方案1】:

如果您使用的是 pandas 0.25+,您可以使用explode,它在每个单元格的列表中创建一个系列并将它们连接起来。类似于pd.concat(pd.Series(x) for x in df['B']),但保留原始索引。然后,您可以将该系列与您的三元组和groupby 进行比较:

s = df['B'].explode()

df[(s == ('BB', 15, 183)).groupby(level=0).any()]

输出:

   A                               B                C
2  3  [(ABC, 56, 76), (BB, 15, 183)]  [(ABC, 25, 45)]
3  4                 [(BB, 15, 183)]  [(BB, 91, 187)]

输出(s):

0      (AA, 4, 11)
0    (ABC, 28, 99)
0    (ABC, 23, 86)
1      (AA, 2, 10)
2    (ABC, 56, 76)
2    (BB, 15, 183)
3    (BB, 15, 183)
Name: B, dtype: object

【讨论】:

  • 感谢您的回答!有关更多上下文,explode() 在这里做什么?
  • explode() 从每个单元格的列表中创建一个系列并将它们连接起来。类似于pd.concat(pd.Series(x) for x in df['B']),但它保留了原始索引。因此我们可以groupby(level=0)
  • 这是有道理的! (可以把这个解释放在答案中吗?我认为这是一个很好的解释。)
【解决方案2】:

你可以通过apply方法做到这一点:

df[df['B'].apply(lambda x: ('BB', 15, 183) in x)]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 2018-01-25
    • 1970-01-01
    • 2016-06-15
    • 2020-03-18
    • 1970-01-01
    相关资源
    最近更新 更多