【问题标题】:groupby+Arithmatic operation on pandas dataframe in pythonpython中对熊猫数据框的groupby +算术运算
【发布时间】:2016-08-07 15:52:38
【问题描述】:

可能是一个愚蠢的问题,但我在两者之间感到困惑,并且在这种情况下如何有效地应用 groupby 的逻辑将不胜感激。

我有一个类似的数据框

 id    NAME    TYPE   SCORE  title
123    DDLJ     cat1   1-6     5
123    DDLJ     cat1   9-10    25
123    DDLJ     cat1     N     5
456    Satya    cat2   9-10    1
456    Satya    cat2    N      3
222    India    cat2   1-6     1

我需要为一个 groupof (id NAME TYPE) 找出一个名为“cat_score”的列,其逻辑应该是“为该组 [标题为 SCORE(9-10) - 标题为 SCORE(1-6)] / [该组的标题总和] "

#ex for group 123, DDLJ cat1  
 cat score = (title at SCORE "9-10" - title at SCORE "1-6") / (Sum of title of that group)
           = (25 - 5) / (35)
           = 0.58

注意:: SCORE 有 3 种类型 ["9-10", "1-6", "N"]。因此,如果对于任何组,任何未找到的分数类别都应视为 0 或可以忽略。

我的最终数据框应该是这样的

 id    NAME    TYPE   SCORE  title  Cat_Score
123    DDLJ     cat1   1-6     5     0.58
123    DDLJ     cat1   9-10    25    0.58
123    DDLJ     cat1     N     5     0.58
456    Satya    cat2   9-10    1     0.34
456    Satya    cat2    N      3     0.34
222    India    cat2   1-6     1      -1

请提出建议。

我尝试了一组

s = round((int(df[(df['id']=='123') & (df['NAME'] == 'DDLJ') & (df['TYPE']=='cat1') & (df['SCORE']=='9-10')]['title'].values[0]) - int(df[(df['id']=='123') & (df['NAME'] == 'DDLJ') & (df['TYPE']=='cat1') & (df['SCORE']=='1-6')]['title'].values[0])) / (int(df['title'].sum())),2)
s = 0.58

但是对于所有组,我都对如何复制感到困惑。

【问题讨论】:

  • 你能检查第二组的结果吗?不应该是(1-0) / 4 = 0.25
  • @ayhan-是的,你是对的

标签: python pandas group-by


【解决方案1】:

我认为如果你先重塑你的 DataFrame 会更容易:

df2 = df.set_index(['id', 'NAME', 'TYPE']).pivot(columns='SCORE').fillna(0)
df2.columns = df.columns.droplevel(0)
df2
Out: 
SCORE           1-6  9-10    N
id  NAME  TYPE                
123 DDLJ  cat1  5.0  25.0  5.0
222 India cat2  1.0   0.0  0.0
456 Satya cat2  0.0   1.0  3.0

现在您可以更轻松地进行这些操作:

(df['9-10'] - df['1-6']) / df.sum(axis=1)
Out: 
id   NAME   TYPE
123  DDLJ   cat1    0.571429
222  India  cat2   -1.000000
456  Satya  cat2    0.250000

为了在合并中使用这些,我将重置索引:

res = ((df['9-10'] - df['1-6']) / df.sum(axis=1)).reset_index()
res
Out: 
    id   NAME  TYPE         0
0  123   DDLJ  cat1  0.571429
1  222  India  cat2 -1.000000
2  456  Satya  cat2  0.250000

最后与原来的DataFrame合并:

df.merge(res)
Out: 
    id   NAME  TYPE SCORE  title         0
0  123   DDLJ  cat1   1-6      5  0.571429
1  123   DDLJ  cat1  9-10     25  0.571429
2  123   DDLJ  cat1     N      5  0.571429
3  456  Satya  cat2  9-10      1  0.250000
4  456  Satya  cat2     N      3  0.250000
5  222  India  cat2   1-6      1 -1.000000

【讨论】:

  • @ayhan-mine 失败并出现错误 ValueError: cannot label index with a null key for df2 = df.set_index(['id', 'NAME', 'TYPE']).pivot( columns='SCORE').fillna(0)
  • 您在其中一列中有 NaN 值吗? (id、NAME 或 TYPE)
  • 不,我已经检查过并且还分别对所有列进行了 fillna()。
  • 我们不需要在数据透视码中设置 value='title' 吗??
  • @ayhan- 通过使用 df2 = pd.tools.pivot.pivot_table(df, values='title', index=['id', 'NAME', 'TYPE'], columns =['得分'])。取而代之的是熊猫 0.16.1 的 set_index...一个已知的错误...非常感谢您的帮助..:)
【解决方案2】:

试试这个来回答你的问题如何应用groupby:

def getScore(gb):
    x = gb[gb['SCORE'] == '9-10']['title'].values.sum()
    y = gb[gb['SCORE'] == '1-6']['title'].values.sum()
    z = float(gb['title'].sum())
    return pd.Series((x-y)/z) 

gb     = df2.groupby(["NAME"])['SCORE', 'title'].apply(getScore).reset_index()
gbdict = dict(gb.values)
gbdict

{'DDLJ': 0.5714285714285714, 'India': -1.0, 'Satya': 0.25}   


df2['cat_score'] = df2['NAME'].map(dict(gb.values))

    id   NAME  TYPE SCORE  title  cat_score
0  123   DDLJ  cat1   1-6      5   0.571429
1  123   DDLJ  cat1  9-10     25   0.571429
2  123   DDLJ  cat1     N      5   0.571429
3  456  Satya  cat2  9-10      1   0.250000
4  456  Satya  cat2     N      3   0.250000
5  222  India  cat2   1-6      1  -1.000000

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-09
    • 2023-04-10
    • 2017-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多