【问题标题】:How to filter a pandas DataFrame according to a list of tuples?如何根据元组列表过滤熊猫数据框?
【发布时间】:2019-05-21 16:46:11
【问题描述】:

如何从一组元组中过滤数据帧,使配对相同?我需要一种更优雅的写作方式。我尽量不使用合并,因为它会降低效率。

所以我有一个名为 tup_list 的元组列表: [('118', '35'), ('35', '35'), ('118', '202') 假设每个元组中的第一个元素是 A,第二个是 B,我试图根据这个 tup_list 过滤我的数据帧,其中配对需要相同。

原始数据框:

A   B
118 35
118 40
35  202
118 1
35  35

根据tup_list过滤后,新的dataframe应该是:

A   B
118 35
35  35

只应返回精确的配对。

目前我使用df= df.merge(tup_list, on=['A','B'], how='inner'). But is not very efficient as my actual data is larger.

请提供更有效的写作方式。

【问题讨论】:

标签: python pandas dataframe filter tuples


【解决方案1】:

使用您的 tup_list 和名为 df 的数据框,这是请求输出的单行:

df[[x in tup_list for x in list(zip(df.A,df.B))]]

【讨论】:

  • 我相信您不需要使用list,因为zip 已经是一个可迭代对象。您可以将代码更改为df[[x in tup_list for x in zip(df.A,df.B)]]
【解决方案2】:

使用布尔索引:

tup_list = [(118, 35), (35, 35), (118, 202)]
df[pd.Series(list(zip(df['A'], df['B']))).isin(tup_list)]

    A   B
0   118 35
4   35  35

list(zip(df['A'], df['B'])) 将您的两列转换为元组列表:

[(118, 35), (118, 40), (35, 202), (118, 1), (35, 35)]

你将把它变成一个系列并使用isin 返回一个布尔值:

0     True
1    False
2    False
3    False
4     True
dtype: bool

可用于布尔索引

【讨论】:

  • 奇怪的是,这不会产生我想要的结果。在它应该显示的 5 对不同的值中,它只显示了 2 对不同的值。
  • @R_abcdefg 它不会在您的实际数据集上产生您想要的结果?
  • 它没有返回我想要的结果。 :(
  • 您确定您的tup_list 正确吗:不是字符串而是实际的ints,或者您的数据框包含ints 而不是字符串。 df['A'] 和 df['B'] 的dtype 是什么?
  • 我的 tuplist 是字符串。 df['A'] 和 df['B'] 的 dtype 都是对象
【解决方案3】:

使用pandas.DataFrame.query,您还可以根据您的元组列表过滤您的数据框

import numpy as np
import pandas as pd

f = [('118', '35'), ('35', '35'), ('118', '202')]
idxs = [df.query('A=='+ t[0] + ' and B==' + t[1]).index.values for t in f]
idxs = np.concatenate(idxs).ravel().tolist()
df2 = df.iloc[idxs,:]
print(df2)
#      A   B
# 0  118  35
# 4   35  35

【讨论】:

    猜你喜欢
    • 2021-12-01
    • 2020-08-08
    • 2020-05-05
    • 2014-12-27
    • 2019-12-09
    • 2021-10-03
    • 2017-12-15
    • 1970-01-01
    • 2019-03-04
    相关资源
    最近更新 更多