在Pandas中尝试使用str.contains和布尔掩码,但仅适用于两个单一值的情况

2024-05-14 01:14:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我要做的是保持所有行都具有相同的唯一性ID,如果其中任何一行在Yurt列中只包含两个“–”实例。你知道吗

我正在考虑通过执行以下操作来使用str.contains和布尔掩码:

df[df['ID'].isin(df.loc[df.Yurt.str.contains('-'), 'ID'].unique())]

…但不确定如何只保留只有两个实例的行,而没有值。你知道吗

示例df:

ID      %       Yurt
abc123  0.833   Bodega
abc123  0.87    -
abc123  0.867   -
abc123  0.812   -
lmn789  0.837   Mickey's
lmn789  0.856   Chopped Cheese
lmn789  0.813   -
lmn789  0.812   -
xyz456  0.111   -
xyz456  0.222   -
xyz456  0.333   -
xyz456  0.444   -

结果数据框:

ID      %       Yurt
lmn789  0.837   Mickey's
lmn789  0.856   Chopped Cheese
lmn789  0.813   -
lmn789  0.812   -

Tags: 实例iddfloccontains掩码strabc123
2条回答

对“ID”列执行groupby,然后使用^{}

df = df.groupby('ID').filter(lambda grp: grp['Yurt'].eq('-').sum() == 2)

输出:

       ID      %            Yurt
4  lmn789  0.837        Mickey's
5  lmn789  0.856  Chopped Cheese
6  lmn789  0.813               -
7  lmn789  0.812               -

您可以使用GroupBy.size来计算范围内的值。然后过滤原始数据帧。你知道吗

nulls = df[df['Yurt'] == '-'].groupby('ID').size()

df = df[df['ID'].isin(nulls[nulls == 2].index)]

print(df)

       ID      %           Yurt
4  lmn789  0.837       Mickey's
5  lmn789  0.856  ChoppedCheese
6  lmn789  0.813              -
7  lmn789  0.812              -

您可能会发现这比自定义lambda函数更有效:

def jpp(df):
    nulls = df[df['Yurt'] == '-'].groupby('ID').size()
    return df[df['ID'].isin(nulls[nulls == 2].index)]

def root(df):
    return df.groupby('ID').filter(lambda grp: grp['Yurt'].eq('-').sum() == 2)

%timeit jpp(df)   # 2.99 ms per loop
%timeit root(df)  # 4.93 ms per loop

相关问题 更多 >