如何使用相同的键对行进行求和?

Vib*_*bhu 5 python sorting dataframe pandas

在我的代码中,df定义如下

df = pd.read_excel(io=file_name, sheet_name=sheet, sep='\s*,\s*')
Run Code Online (Sandbox Code Playgroud)

我有一个看起来像这样的[86 rows x 1 columns]数据框dfprint(df)

          0
Male    511
Female  461
Male    273
Female  217
Male    394
Female  337
Female  337
Male    337
...
Run Code Online (Sandbox Code Playgroud)

我希望编写一个像这样mergeMaleFemale条目的代码

          0   1   2   3 ...
Male    511 273 394 337 ...
Female  461 217 337 337 ...
Run Code Online (Sandbox Code Playgroud)

我需要做的最后一项任务是.sum()男性排,然后是女排,以获得每个性别的总数.我是python和pandas的新手,到目前为止我还没有取得多大进展.任何帮助,教程,文档都会很棒!谢谢!

编辑:keys我指的是索引.我希望这些男性和女性的标签可以用来"聚集"这些行,但我不知道如何.

编辑:我已经完成了我的最后一项任务

print(df.ix['Female'].sum())
print(df.ix['Male'].sum())
Run Code Online (Sandbox Code Playgroud)

但我还没有完成我的最新任务.有任何想法吗?

jez*_*ael 5

为通过重新整形创建MultiIndexGroupBy.cumcount新列名称创建unstack:

df.index = [df.index, df.groupby(level=0).cumcount()]

print (df)
            0
Male   0  511
Female 0  461
Male   1  273
Female 1  217
Male   2  394
Female 2  337
       3  337
Male   3  337
Run Code Online (Sandbox Code Playgroud)
df = df[0].unstack()
print (df)
          0    1    2    3
Female  461  217  337  337
Male    511  273  394  337
Run Code Online (Sandbox Code Playgroud)

然后sum所有行axis=1:

print (df.sum(axis=1))

Female    1352
Male      1515
dtype: int64
Run Code Online (Sandbox Code Playgroud)


jpp*_*jpp 1

您可以使用concat+ transpose

cats = ['Male', 'Female']

res = pd.concat([pd.DataFrame(group.values) for _, group in df.groupby(level=0)],
                axis=1, ignore_index=True)\
        .rename(columns=dict(enumerate(cats)))\
        .transpose()

print(res)

          0    1    2    3
Male    511  273  394  337
Female  461  217  337  337
Run Code Online (Sandbox Code Playgroud)

性能基准测试

concat+ 的transpose性能似乎比cumcount+好约 4 倍unstack。通常情况并非如此,但在我们有少量大群体的情况下确实如此,例如这里。

def jpp(df):
    cats = ['Male', 'Female']
    res = pd.concat([pd.DataFrame(group.values) for _, group in df.groupby(level=0)],
                    axis=1, ignore_index=True)\
            .rename(columns=dict(enumerate(cats)))\
            .transpose()
    return res

def jez(df):    
    df.index = [df.index, df.groupby(level=0).cumcount()]
    df = df[0].unstack()
    return df

df2 = pd.concat([df]*10000)

%timeit jpp(df2.copy())  # 12 ms
%timeit jez(df2.copy())  # 52.7ms
Run Code Online (Sandbox Code Playgroud)