【问题标题】:How to keep all columns after groupby and averaging a DataFrame [duplicate]如何在 groupby 和平均 DataFrame 之后保留所有列 [重复]
【发布时间】:2020-12-16 20:13:12
【问题描述】:

我有一个名为“数据”的数据框:

     USER  VALUE VALUE2
0    XOXO     21    AAA
1   ABC-1      2    BBB
2  ABC-1B      4    CCC
3   ABC-2      4    DDD
4  ABC-2B      6    EEE
5    PEPE     12    FFF

我通过一些代码运行它来组合相似的名称:

data = pd.DataFrame({'USER':['XOXO','ABC-1','ABC-1B','ABC-2','ABC-2B', 'PEPE'], 'VALUE':[21,2,4,4,6,12], 'VALUE2':['AAA','BBB','CCC','DDD','EEE', 'FFF']})
data.USER = data.USER.str.replace('(-\d)B', r"\1")
data = data.groupby('USER', as_index=False, sort=False).VALUE.mean()

但是我最终得到了一个像这样的数据框,其中 VALUE2 被丢弃:

    USER  VALUE
0   XOXO     21
1  ABC-1      3
2  ABC-2      5
3   PEPE     12

如何修改代码以通过保留原始 USER 的 VALUE2 来保留 VALUE2?所以用户'ABC-1'的VALUE2将保留'BBB'和'ABC-2'的'DDD'

    USER  VALUE   VALUE2
0   XOXO     21      AAA
1  ABC-1      3      BBB
2  ABC-2      5      DDD
3   PEPE     12      FFF

【问题讨论】:

  • 聚合 VALUEVALUE2 first
  • 您如何决定是否为用户ABC-1 使用BBB 而不是CCC
  • Groupby USER 剥离尾随 B 以获得 VALUE 的平均值。布尔选择的适当组合应该消除不受欢迎的VALUE2。见下文
  • @stackoverflow 这有帮助吗? :-)?

标签: python pandas dataframe


【解决方案1】:

Groupby USER 去掉尾随的 B 后。然后使用 .str.contains().isin() 实现适当的布尔选择和过滤最终数据帧

  df['VALUE']=df[['USER', 'VALUE', 'VALUE2']].groupby(df.USER.str.split('(?<=[1-2])(B)').str[0])['VALUE'].transform('mean')
   df[~((df.USER.str.contains('ABC'))&(~df.VALUE2.isin(['BBB','DDD'])))]

      
        USER  VALUE VALUE2
    0   XOXO     21    AAA
    1  ABC-1      3    BBB
    3  ABC-2      5    DDD
    5   PEPE     12    FFF

工作原理

#Strip trailing B in USER
df.USER=df.USER.str.split('(?<=[1-2])(B)').str[0]

    USER  VALUE VALUE2
0   XOXO     21    AAA
1  ABC-1      2    BBB
2  ABC-1      4    CCC
3  ABC-2      4    DDD
4  ABC-2      6    EEE
5   PEPE     12    FFF

#使用 groupby 变换查找均值

df['VALUE']=df.groupby(df.USER.str.split('(?<=[1-2])(B)').str[0])['VALUE'].transform('mean')
print(df)

USER  VALUE VALUE2
0   XOXO     21    AAA
1  ABC-1      3    BBB
2  ABC-1      3    CCC
3  ABC-2      5    DDD
4  ABC-2      5    EEE
5   PEPE     12    FFF

#Boolean 选择任何包含ABC; (df.USER.str.contains('ABC')) 和哪个没有BBBDDD(~df.VALUE2.isin(['BBB','DDD']))

#合并两个选择,然后使用~反转选择

~((df.USER.str.contains('ABC'))&(~df.VALUE2.isin(['BBB','DDD'])))

#最后过滤数据帧

【讨论】:

  • 谢谢@G。安德森,更正了。包括平均值。
  • 还没有机会运行您的解决方案,但是通过查看df[~((df.USER.str.contains('ABC'))&amp;(~df.VALUE2.isin(['BBB','DDD'])))],它似乎是硬编码的?我一直在寻找一种方法来从我们“合并”的 USER 中保留 VALUE2。假设用户 XXX-1 和 XXX-1T 分别有 VALUE2 EEE 和 TTT。将 USER 组合后将是 XXX-1 和 VALUE2 EEE
猜你喜欢
  • 2018-08-19
  • 1970-01-01
  • 2023-02-17
  • 2023-02-22
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
  • 2019-10-01
  • 2018-07-30
相关资源
最近更新 更多