我不确定该怎么做。。。我有一列"状态"和另一列"MultiID"。我正在尝试删除所有具有相同MultiID的行,但前提是它包含状态"B"。
import pandas as pd
# initialise data of lists.
data = {'Status':['A', 'B', 'A', 'C', 'C', 'A', 'B', 'A'],
'MultiID': [1, 1, 2, 2, 2, 3, 3, 3]}
# Create DataFrame
df = pd.DataFrame(data)
# Print the output.
print(df)
由于MultiID的1和3中有一个"B",输出应该是:
0 A 2
1 C 2
2 C 2
这里有一个简短的解决方案:
new_df = df.groupby('MultiID').filter(lambda g: ~g['Status'].eq('B').any())
输出:
>>> new_df
Status MultiID
2 A 2
3 C 2
4 C 2
这里有一种没有groupby
的方法。获取";MultiID";s行,其中Status=="B"
,然后过滤没有这些MultiID:的行
MultiIDs_w_Bs = df.loc[df['Status'].eq('B'), 'MultiID']
out = df[~df['MultiID'].isin(MultiIDs_w_Bs)]
输出:
Status MultiID
2 A 2
3 C 2
4 C 2
无需groupby
out = df.loc[~df.MultiID.isin(df.loc[df.Status.eq('B'),'MultiID'])]
Out[169]:
Status MultiID
2 A 2
3 C 2
4 C 2
根据您的条件筛选出数据帧之前,请使用groupby
。这里transform
允许向组中的每个成员广播布尔结果。
out = df[df.groupby('MultiID')['Status'].transform(lambda x: all(x != 'B'))]
print(out)
# Output
Status MultiID
2 A 2
3 C 2
4 C 2
尝试:
df[~df['Status'].eq('B').groupby(df['MultiID']).transform('any')]
输出:
Status MultiID
2 A 2
3 C 2
4 C 2
详细信息:
- 创建一个状态等于B的布尔序列
- 按MultiID对该系列进行分组
- 如果该组中的任何记录为True,则使用transform整组True
- 反转True和False并对原始数据帧进行布尔筛选
s = ['A', 'B', 'A', 'C', 'C', 'A', 'B', 'A']
m = [1, 1, 2, 2, 2, 3, 3, 3]
# Loop through lists and remove the element if its status is B
for i in range(len(m)-1):
if s[i] == 'B':
del m[i]
# Remove all B's from s
while 'B' in s:
s.remove('B')
print(s)
print(m)
给出
['A', 'A', 'C', 'C', 'A', 'A']
[1, 2, 2, 2, 3, 3]