【问题标题】:Apply multiple filter on column using nested tuple使用嵌套元组在列上应用多个过滤器
【发布时间】:2021-10-24 04:25:17
【问题描述】:

正在尝试向元组过滤器添加加法条件......

没有附加条件的当前工作元组过滤器(稍后讨论):

import pandas as pd

data = [['A',23], ['D',50], ['C',32], ['D',21], ['D',24], ['B',20], ['C',68], ['A',52], ['A',41],[ 'D',44], ['B',29], ['B',70], ['B',33], ['C',56], ['A',72]]

df = pd.DataFrame(data, columns = ['group', 'age'])

group_mask = {(20, 30): 'A', (25, 30): 'B', (65, 70): 'C', (40, 50): 'D'}

df['range'] = df['group'].map({v:k for k, v in group_mask.items()})
df['in_range'] = (df['range'].str[0] <= df['age'])  &  (df['age'] <= df['range'].str[1])

#filtered
df = df[df['in_range']]
df.drop(columns=['range', 'in_range'], inplace=True)

上面的代码将数据帧过滤到年龄等于或在每个相应组的 group_mask 中设置的范围之间的行。 从而产生以下输出...

      group   age
0     A       23
1     D       50
6     C       68
9     D       44
10    B       29

但是,我需要考虑一个附加条件(列);专栏gender。根据gendergroupage 过滤器范围会有所不同

数据现在已被修改,以包括这一附加列:

data = [['A', 'male', 23], ['D','female',50], ['C','male',32], ['D','male',21], ['D','female',24], ['B','female',20], ['C','male',68], ['A','male',52], ['A','male',41],[ 'D','male',44], ['B','female',29], ['B','female',70], ['B','female',33], ['C','female',56], ['A','female',72]]

df = pd.DataFrame(data, columns = ['group', 'gender', 'age'])

但是,将现有的 group_mask 元组过滤器调整为现在包含“性别”相关范围是我遇到的问题,如下所示。

我尝试过从....更改...

group_mask = {(20, 30): 'A', (25, 30): 'B', (65, 70): 'C', (40, 50): 'D'}

到....

group_mask  = {(((20, 30), 'A') , 'male' ), (((25, 30), 'B') , 'male' ), (((65, 70), 'C') , 'male' ), (((40, 50), 'D'), 'male' ), \
(((60, 80), 'A') , 'female'), (((15, 30), 'B'),  'female'), (((50, 60), 'C'), 'female'), (((30, 40), 'D'), 'female' )}

..然后重新应用map 和过滤器....

df['range'] = df[['group', 'gender']].map({v:k for k, v in group_mask .items()})
df['in_range'] = (df['range'].str[0] <= df['age'])  &  (df['age'] <= df['range'].str[1])

但是,它会引发错误消息AttributeError: 'DataFrame' object has no attribute 'map'

首先,我不确定修改后的group_mask 的格式是否正确,其次我不确定如何更正map 函数。

需要帮助。提前谢谢你。

【问题讨论】:

  • 您的意思是df[['group', 'gender']].map({v:k for k, v in group_mask .items()}) 而不是df['group', 'gender'].map({v:k for k, v in group_mask .items()})
  • 另外,group_mask 不是字典,对吧? group_mask .items() 是什么意思?
  • 当我尝试df[['group', 'gender']].map({v:k for k, v in group_mask .items()}) 时,我收到以下错误消息.....AttributeError: 'DataFrame' object has no attribute 'map'
  • 是的,它并没有完全解决问题,但它解决了部分问题,因为当您查询两列时,您需要使用df[['group', 'gender']] 之类的列表而不是df['group', 'gender']
  • “另外,group_mask 不是字典,对吗?group_mask .items() 是什么意思?” group_mask 在顶部的第一个示例中使用,现在我想添加 gender 作为键或条件

标签: python pandas dataframe tuples filtering


【解决方案1】:

你可以让group_mask 变成这样:

group_mask = {(30, 40): ('D', 'female'), (25, 30): ('B', 'male'), (40, 50): ('D', 'male'), (65, 70): ('C', 'male'), (60, 80): ('A', 'female'), (20, 30): ('A', 'male'), (15, 30): ('B', 'female'), (50, 60): ('C', 'female')}

要应用地图,你可以有这样的东西:

df['range']=df.apply(lambda x: [(x[0],x[1])], axis=1, result_type='expand')[0].map({v:k for k, v in group_mask .items()})
df['in_range'] = (df['range'].str[0] <= df['age'])  &  (df['age'] <= df['range'].str[1])

【讨论】:

  • 这行得通!但是,数据最初是我删除的参考列col_ref。当包含col_ref(我需要)时,代码会产生空df...我尝试将result_type更改为broadcast以获取所有原始列,但产生错误ValueError: too many dims to broadcast
  • @DiopChopra 你能用(x[1],x[2]) 替换(x[0],x[1]) 并尝试运行它吗?
  • 这行得通,但是如果我还想要所有其他原始列怎么办,我怎样才能让它们回到 df 中?还有20个
  • 您正在尝试根据组和性别值进行映射。因此,请确保您相应地选择组和性别列。在您的第一种情况下,组在第一列,性别在第二列,因此 (x[0],x[1]) 可以工作。在第二种情况下,组在第二列,性别在第三列,这就是 (x[1],x[2]) 可以工作的原因。现在,在新数据框中,如果您在第 m 列中有组,在第 n 列中有性别,那么您可以使用(x[m-1],x[n-1])
  • (x[m-1],x[n-1]) 抱歉,我不明白这一点。事实上,原来的df 有 10 列。 group 列是第 2 列(列索引 1),gender 是第 3 列(列索引 2) - 我该怎么写?
猜你喜欢
  • 1970-01-01
  • 2020-12-06
  • 2020-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-13
相关资源
最近更新 更多