我需要的东西看起来很基本,但我正在为此苦苦挣扎,所以我很感激你的帮助。
此代码:
data = pd.DataFrame({'id' : ['a100', 'a100', 'a100', 'a200', 'a200', 'a200','a300','a300', 'a300', 'a400', 'a400', 'a400', 'a500', 'a500', 'a500', 'a600', 'a600', 'a600', 'a700', 'a700', 'a700', 'a800', 'a800', 'a800', 'a900', 'a900', 'a900'],
'type': ['euro', 'dollar', 'yen', 'euro', 'dollar', 'yen','euro', 'dollar', 'yen', 'euro', 'dollar', 'yen', 'euro', 'dollar', 'yen', 'euro', 'dollar', 'yen', 'euro', 'dollar', 'yen', 'euro', 'dollar', 'yen', 'euro', 'dollar', 'yen'],
'model': ['EQ', 'EQ', 'EQ', 'MC', 'MC', 'MC', 'EQ','EQ', 'EQ', 'MC', 'MC', 'MC', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ'],
'status_ant': ['A', 'A', 'A', 'A', 'A', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'A', 'A', 'A', 'B', 'C', 'B', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'],
'status': ['B', 'C', 'A', 'B', 'C', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'C', 'B', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'A', 'B', 'A', 'C', 'C']
})
导致此 df:
id type model status_ant status
0 a100 euro EQ A B
1 a100 dollar EQ A C
2 a100 yen EQ A A
3 a200 euro MC A B
4 a200 dollar MC A C
5 a200 yen MC A A
6 a300 euro EQ B A
7 a300 dollar EQ C A
8 a300 yen EQ A A
9 a400 euro MC B A
10 a400 dollar MC C A
11 a400 yen MC A A
12 a500 euro EQ A B
13 a500 dollar EQ A C
14 a500 yen EQ A B
15 a600 euro EQ B A
16 a600 dollar EQ C A
17 a600 yen EQ B A
18 a700 euro EQ A A
19 a700 dollar EQ A A
20 a700 yen EQ A B
21 a800 euro EQ A B
22 a800 dollar EQ A A
23 a800 yen EQ A B
24 a900 euro EQ A A
25 a900 dollar EQ A C
26 a900 yen EQ A C
我需要使用某些条件过滤我想要的行。我需要的逻辑是这个:
首先,我要提到的这些条件只适用于模型 == 'EQ' 的行。
如果有一行:
status_ant == 'A' and status == 'B' and type == 'euro'
并且在同一组中还有另一行(按 ID)
status_ant == 'A' and status == 'C' and type == 'dollar'
删除这两行(否则,保留它们)。相同的逻辑适用于行:
status_ant == 'B' and status == 'A' and type == 'euro'
并且在同一组中还有另一行(按 ID)
status_ant == 'C' and status == 'A' and type == 'dollar'
无论 status_ant 和 status 中的值是什么,都不应删除 type == 'yen' 的行。
注意:我知道这可能会令人困惑,但我想要的结果数据帧就是这个(它很好地体现了我提到的所有条件):
id type model status_ant status
2 a100 yen EQ A A
3 a200 euro MC A B
4 a200 dollar MC A C
5 a200 yen MC A A
8 a300 yen EQ A A
9 a400 euro MC B A
10 a400 dollar MC C A
11 a400 yen MC A A
14 a500 yen EQ A B
17 a600 yen EQ B A
18 a700 euro EQ A A
19 a700 dollar EQ A A
20 a700 yen EQ A B
21 a800 euro EQ A B
22 a800 dollar EQ A A
23 a800 yen EQ A B
24 a900 euro EQ A A
25 a900 dollar EQ A C
26 a900 yen EQ A C
我正在寻找答案并在这里找到了类似的东西:Pandas: Comparing rows within groups
但无法使其适用于我的代码。
非常感谢您的帮助和时间。 谢谢
答案 0 :(得分:1)
代码还是一样的:
print (df[~(df.model.eq('EQ') & df.status_ant.ne(df.status))])
输入数据:
data = pd.DataFrame({'id' : ['a100', 'a100', 'a100', 'a200', 'a200', 'a200','a300','a300', 'a300', 'a400', 'a400', 'a400'],
'model' : ['EQ', 'EQ', 'EQ', 'MC', 'MC', 'MC', 'EQ','EQ', 'EQ', 'MC', 'MC', 'MC', ],
'status_ant' : ['A', 'A', 'A', 'A', 'A', 'A', 'B', 'C', 'A', 'B', 'C', 'A'],
'status': ['B', 'C', 'A', 'B', 'C', 'A', 'A', 'A', 'A', 'A', 'A', 'A']
})
这被加载到数据帧中:
id model status_ant status
0 a100 EQ A B #exclude this row
1 a100 EQ A C #exclude this row
2 a100 EQ A A
3 a200 MC A B
4 a200 MC A C
5 a200 MC A A
6 a300 EQ B A #exclude this row
7 a300 EQ C A #exclude this row
8 a300 EQ A A
9 a400 MC B A
10 a400 MC C A
11 a400 MC A A
更新的数据帧:
id model status_ant status
2 a100 EQ A A
3 a200 MC A B
4 a200 MC A C
5 a200 MC A A
8 a300 EQ A A
9 a400 MC B A
10 a400 MC C A
11 a400 MC A A
你在找这个吗:
print (df[~(df.model.eq('EQ') & df.status_ant.ne(df.status))])
请注意,您不需要进行分组。您无法进行分组,因为您实际上是在尝试获取数据的子集。
首先它会检查是否df['model'] == 'EQ'
。如果为 true,则它会检查是否 df['status_ant'] != df['status']
。
通过给出 df['status_ant'] != df['status']
,您正在检查所有条件。
status_ant == 'A' and status == 'B', AND status_ant == 'A' and status == 'C'
和
status_ant == 'B' and status == 'A', AND status_ant == 'C' and status == 'A'
输出结果为:
id model status_ant status
2 a100 EQ A A
3 a200 MC A B
4 a200 MC A C
5 a200 MC A A
8 a300 EQ A A
9 a400 MC B A
10 a400 MC C A
11 a400 MC A A
注意:如果您在 status_ant
和 status
中有其他值,这将不起作用。例如,如果 status_ant
是 A
并且 status
是 D
或 E
并且您希望包含该记录,那么我需要添加一个附加条件.
如果您只想限制对 A
、B
和 C
的检查,那么您可以给出:
print (df[~(df.model.eq('EQ') & df.status_ant.isin(['A','B','C']) & df.status.isin(['A','B','C']) & df.status_ant.ne(df.status))])
输出结果为:
我用来创建输入数据帧的源代码:
data = pd.DataFrame({'id' : ['a100', 'a100', 'a100', 'a100','a200', 'a200', 'a200','a300','a300', 'a300', 'a400', 'a400', 'a400'],
'model' : ['EQ', 'EQ', 'EQ', 'EQ','MC', 'MC', 'MC', 'EQ','EQ', 'EQ', 'MC', 'MC', 'MC', ],
'status_ant' : ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'C', 'A', 'B', 'C', 'A'],
'status': ['B', 'C', 'A', 'D', 'B', 'C', 'A', 'A', 'A', 'A', 'A', 'A', 'A']
})
df = pd.DataFrame(data)
输入数据帧:
id model status_ant status
0 a100 EQ A B #exclude this row
1 a100 EQ A C #exclude this row
2 a100 EQ A A #include this row
3 a100 EQ A D #include this row
4 a200 MC A B
5 a200 MC A C
6 a200 MC A A
7 a300 EQ B A #exclude this row
8 a300 EQ C A #exclude this row
9 a300 EQ A A #include this row
10 a400 MC B A
11 a400 MC C A
12 a400 MC A A
输出数据帧:
id model status_ant status
2 a100 EQ A A #included
3 a100 EQ A D #included
4 a200 MC A B
5 a200 MC A C
6 a200 MC A A
9 a300 EQ A A #included
10 a400 MC B A
11 a400 MC C A
12 a400 MC A A
参见索引 3。它有 status = 'D'
并包含在您的结果集中。
答案 1 :(得分:1)
如果对于每个 id
列 type
的唯一值是可能的测试,如果每组 True
的总和为 2
,您可以使用此解决方案:
m0 = data['model']=='EQ'
m1 = (data['status_ant'] == 'A') & (data['status'] == 'B') & (data['type'] == 'euro')
m2 = (data['status_ant'] == 'A') & (data['status'] == 'C') & (data['type'] == 'dollar')
m3 = (data['status_ant'] == 'B') & (data['status'] == 'A') & (data['type'] == 'euro')
m4 = (data['status_ant'] == 'C') & (data['status'] == 'A') & (data['type'] == 'dollar')
mask = m0 & (m1 | m2 | m3 | m4)
mask_groups = mask.groupby(data['id']).transform('sum').eq(2)
data = data[~mask | ~mask_groups]
print (data)
id type model status_ant status
2 a100 yen EQ A A
3 a200 euro MC A B
4 a200 dollar MC A C
5 a200 yen MC A A
8 a300 yen EQ A A
9 a400 euro MC B A
10 a400 dollar MC C A
11 a400 yen MC A A
14 a500 yen EQ A B
17 a600 yen EQ B A
18 a700 euro EQ A A
19 a700 dollar EQ A A
20 a700 yen EQ A B
21 a800 euro EQ A B
22 a800 dollar EQ A A
23 a800 yen EQ A B
24 a900 euro EQ A A
25 a900 dollar EQ A C
26 a900 yen EQ A C
如果可能的值不是唯一的,则可以通过 any
进行测试,如果每个组匹配,则更改 a100
的数据:
data = pd.DataFrame({'id' : ['a100', 'a100', 'a100', 'a200', 'a200', 'a200','a300','a300', 'a300', 'a400', 'a400', 'a400', 'a500', 'a500', 'a500', 'a600', 'a600', 'a600', 'a700', 'a700', 'a700', 'a800', 'a800', 'a800', 'a900', 'a900', 'a900'],
'type': ['euro', 'dollar', 'dollar', 'euro', 'dollar', 'yen','euro', 'dollar', 'yen', 'euro', 'dollar', 'yen', 'euro', 'dollar', 'yen', 'euro', 'dollar', 'yen', 'euro', 'dollar', 'yen', 'euro', 'dollar', 'yen', 'euro', 'dollar', 'yen'],
'model': ['EQ', 'EQ', 'EQ', 'MC', 'MC', 'MC', 'EQ','EQ', 'EQ', 'MC', 'MC', 'MC', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ', 'EQ'],
'status_ant': ['A', 'A', 'A', 'A', 'A', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'A', 'A', 'A', 'B', 'C', 'B', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'],
'status': ['B', 'C', 'C', 'B', 'C', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'C', 'B', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'A', 'B', 'A', 'C', 'C']
})
m0 = data['model']=='EQ'
m1 = (data['status_ant'] == 'A') & (data['status'] == 'B') & (data['type'] == 'euro')
m2 = (data['status_ant'] == 'A') & (data['status'] == 'C') & (data['type'] == 'dollar')
m3 = (data['status_ant'] == 'B') & (data['status'] == 'A') & (data['type'] == 'euro')
m4 = (data['status_ant'] == 'C') & (data['status'] == 'A') & (data['type'] == 'dollar')
mask1 = m0 & (m1 | m3)
mask2 = m0 & (m2 | m4)
mask_euro = mask1.groupby(data['id']).transform(any)
mask_dolar = mask2.groupby(data['id']).transform(any)
data = data[~(mask1 | mask2) | ~(mask_euro & mask_dolar)]
print (data)
id type model status_ant status
3 a200 euro MC A B
4 a200 dollar MC A C
5 a200 yen MC A A
8 a300 yen EQ A A
9 a400 euro MC B A
10 a400 dollar MC C A
11 a400 yen MC A A
14 a500 yen EQ A B
17 a600 yen EQ B A
18 a700 euro EQ A A
19 a700 dollar EQ A A
20 a700 yen EQ A B
21 a800 euro EQ A B
22 a800 dollar EQ A A
23 a800 yen EQ A B
24 a900 euro EQ A A
25 a900 dollar EQ A C
26 a900 yen EQ A C