【问题标题】:Is there a way to use pandas .isin() function with multiple lists?有没有办法将 pandas .isin() 函数与多个列表一起使用?
【发布时间】:2020-03-17 01:14:52
【问题描述】:
    classes money    mask
student         
6   psp   -26.23    adj|psp  # keep
6   tnt   0.00      adj|psp
6   nvm   -87.42    adj|psp
6   alw   0.00      adj|psp
6   tnt   -14.87    adj|psp
6   adj   9.55      adj|psp  # keep
6   psp   -18.56    adj|psp  # keep
6   wzi   -17.41    adj|psp
6   nvm   65.97     adj|psp
6   psp   27.41     adj|psp  # keep
89  alw   -180.33   alw      # keep
89  alw   -869.44   alw      # keep
89  tnt   -95.66    alw
89  wzi   -35.43    alw
89  nvm   -144.90   alw
89  alw   180.23    alw      # keep
89  tnt   35.43     alw
105 tnt   -24.01    tnt      # keep
105 wzi   213.13    tnt
105 ins   -26.06    tnt
105 tnt   60.81     tnt      # keep

我想过滤此数据框,以便我只有每个帐户对应于掩码的行。例如,对于学生 6,我只想要具有“adj”或“psp”类的行。

我尝试做 .isin() 但我使用的列表不断变化,所以有什么想法如何最有效地做到这一点?

最后,我希望得到这些类的总和,并标记大于零的类。如果可能的话,我想把下面的循环变成更有效的东西。谢谢!

bad_list = []

for i in test.index.unique():
    df_ = test.loc[i]
    mask_class = df_["mask"].str.split("|")
    mask_class = mask_class.iloc[0]
    df_mask = df_[df_['classes'].isin(mask_class)]
    if(sum(df_mask["money"])>0):
        bad_list.append(i)
    ```

【问题讨论】:

  • 保留第 89 行和第 105 行的条件是什么?
  • 对于每个学生,所以对于第 89 行和第 105 行,我想保留与掩码匹配的行。所以对于学生 6,我想保留所有行与 pspadj 类。对于学生 89,我想保留所有带有班级 alw 的行,对于 105,我想保留所有带有 tnt 的行。一旦我有了这些,我将总结这些行的钱,如果它们是肯定的,则将其添加到“坏”列表中
  • 谢谢@Anna,我编辑了我的回复以适合你的,请检查

标签: python pandas filter isin


【解决方案1】:

如果您的情况因学生而异,您可以在字典中详细说明并使用 groupby 申请

condition = {6:['adj','psp'],
         89:['alw'],
        105:['tnt']}

df1.groupby('student').apply(lambda x: x.loc[x['classes'].isin(condition[x['student'].iloc[0]])])

输出:

        student classes money
student             
6   0   6   psp -26.23
    5   6   adj 9.55
    6   6   psp -18.56
    9   6   psp 27.41
89  10  89  alw -180.33
    11  89  alw -869.44
    15  89  alw 180.23
105 17  105 tnt -24.01
    20  105 tnt 60.81

【讨论】:

  • 谢谢!一次性为所有学生做这件事,怎么可能做到?
【解决方案2】:

您可以创建一个包含掩码列splitexplode 的临时列,并仅过滤与临时列匹配的行:

(df
  #create temporary column
 .assign(mask_expand = lambda x: x['mask'].str.split('|'))
  # 'explode' column into individual elements per row
 .explode('mask_expand')
  #keep only rows where the values in classes are in mask_expand(the temporary column)
 .query('classes == mask_expand')
  #get rid of the temporary column
 .drop('mask_expand', axis = 1)
 )

    student classes money   mask
 0     6      psp   -26.23  adj|psp
 5     6      adj   9.55    adj|psp
 6     6      psp   -18.56  adj|psp
 9     6      psp   27.41   adj|psp
 10    89     alw   -180.33 alw
 11    89     alw   -869.44 alw
 15    89     alw   180.23  alw
 17    105    tnt   -24.01  tnt
 20    105    tnt   60.81   tnt

【讨论】:

    猜你喜欢
    • 2020-04-10
    • 2020-07-07
    • 1970-01-01
    • 2021-10-02
    • 2021-05-02
    • 2018-03-15
    • 2016-11-01
    • 1970-01-01
    • 2018-09-07
    相关资源
    最近更新 更多