【问题标题】:Multiple conditional statements with groupby in pandaspandas 中带有 groupby 的多个条件语句
【发布时间】:2020-05-31 08:01:02
【问题描述】:

我有一个类似于以下的数据集。

date,score
3/1/16,0.6369
5/1/16,-0.2023
6/1/16,0.04
7/1/16,0.0772
9/1/16,-0.4215
12/1/16,0.2960
15/1/16,0.25
15/1/16,0.7684

我想在乐谱上应用以下条件。

Con1: if the score is >.05, count that as positive for that date
Con2: if the score is  -0.05<=score <=.05, count that as neutral for that date
Con3: Else, count that as negative for that date
And add a new_column to the DataFrame alongside the score to put the 'negative'/'positive'/'neutral' result

预期输出:

date, score, mood
3/1/16,0.6369, positive
5/1/16,-.2023, negative
6/1/16,0.04, neutral

我在同一日期有多个分数。所以,我想到了使用多列('date'和'score')的groupby,并通过if条件并向DataFrame添加一个新列['mood']。

我尝试过的:

df =pd.read_csv('file.csv')
def SortMood(df)
df['mood']=[] #empty column as a list in the df to store the mood 
 for score in df['score']:
      if score>(0.05):
            df['mood'].append('positive')
      elif -0.05<=score <=.05:
            df['mood'].append('neutral')
      else:
          df['mood'].append('negative')

我知道这个函数是错误的(我得到一个 ValueError)。因此,任何帮助表示赞赏。谢谢。

【问题讨论】:

  • 当同一日期的不同分数给出不同答案时,您的预期输出是什么?
  • @andrew_reece 它是根据 if/else 语句。实际上,同一天我有很多不同的分数。谢谢
  • @Non_linear 尚不清楚 if/else 语句在同一日期有多个评估的情况下应如何应用。您是否期望每个日期只有一个输出?如果是这样,那将需要groupby。如果您可以 (a) 指定完整的预期输出并且 (b) 在同一日期包含具有两个不同结果的边缘情况,那将会很有帮助。 (目前 15/1/16 有两个条目,但它们都评估为正面。)
  • @andrew_reece 我应该说的。但是,您建议的解决方案也可以解决此问题。我刚刚检查了一个日期的输出结果,其中有 3 个不同的案例(正面、负面和中性)得分不同,它似乎对所有这些案例都进行了正确分类。谢谢。

标签: python pandas csv


【解决方案1】:

有多种方法可以做到这一点。与您的方法非常相似的是 pandas 的 apply 方法:

def get_mood(row):
    if row['score'] > 0.05:
        return 'positive'
    elif row['score'] > -0.05:
        return 'neutral'
    else:
        return 'negative'
df['mood'] = df.apply(get_mood, axis=1)

或者用 lambda 表达式将其缩短为:

df['mood'] = df.apply(lambda x: 'positive' if x > 0.05 else ('neutral' if x > -0.05 else 'negative'), axis=1)

或者使用map:

df.loc[:,'mood'] = df['score'].map(lambda x: 'positive' if x > 0.05 else ('neutral' if x > -0.05 else 'negative'))

我认为这应该比应用快很多

【讨论】:

    【解决方案2】:

    使用pd.cut 将您的数据分类为:

    df['mood'] = pd.cut(df['score'], 
                        bins=[-np.inf, -.05, .05, np.inf], 
                        labels=['negative', 'neutral', 'positive'])
    
          date   score      mood
    0   3/1/16  0.6369  positive
    1   5/1/16 -0.2023  negative
    2   6/1/16  0.0400   neutral
    3   7/1/16  0.0772  positive
    4   9/1/16 -0.4215  negative
    5  12/1/16  0.2960  positive
    6  15/1/16  0.2500  positive
    7  15/1/16  0.7684  positive
    

    或者使用numpy.select进行向量化多条件列:

    conditions = [
        df['score'].lt(-.05),
        df['score'].between(-.05, 0.05)
    ]
    
    df['mood'] = np.select(conditions, ['negative', 'neutral'], default='positive')
    
          date   score      mood
    0   3/1/16  0.6369  positive
    1   5/1/16 -0.2023  negative
    2   6/1/16  0.0400   neutral
    3   7/1/16  0.0772  positive
    4   9/1/16 -0.4215  negative
    5  12/1/16  0.2960  positive
    6  15/1/16  0.2500  positive
    7  15/1/16  0.7684  positive
    

    【讨论】:

    • 这几乎肯定是比使用apply 更快的解决方案。对于 OP,如果效率很重要,我建议使用@Erfan 的答案。
    • 我总是忘记cut,很好的解决方案+1
    • 是的。这绝对比 andrew_reece 的解决方案快得多。并且非常适合我的庞大数据集(数百万行)。我会改变它。谢谢。
    【解决方案3】:

    使用apply:

    def determine_mood(row, thresh=.05):
        if row.score < -thresh:
            return "negative"
        elif row.score > thresh:
            return "positive"
        else:
            return "neutral"
    
    df["mood"] = df.apply(determine_mood, axis=1)
    
    df
          date   score      mood
    0   3/1/16  0.6369  positive
    1   5/1/16 -0.2023  negative
    2   6/1/16  0.0400   neutral
    3   7/1/16  0.0772  positive
    4   9/1/16 -0.4215  negative
    5  12/1/16  0.2960  positive
    6  15/1/16  0.2500  positive
    7  15/1/16  0.7684  positive
    

    【讨论】:

      猜你喜欢
      • 2017-07-08
      • 2020-05-24
      • 2022-01-23
      • 2021-04-06
      • 2021-04-30
      • 1970-01-01
      • 1970-01-01
      • 2017-06-24
      • 1970-01-01
      相关资源
      最近更新 更多