【问题标题】:Calculate a mean of pandas dataframe whose cells are list计算单元格为列表的熊猫数据框的平均值
【发布时间】:2018-07-16 14:01:56
【问题描述】:

假设我有以下熊猫数据框

import pandas as pd
import numpy as np
df= pd.DataFrame(np.nan, columns =["A","B","C"], index =np.arange(5))
df=df.astype(object)
for c in list(df):
    for i in df.index.values:
        df.at[i, c]=np.arange(5).tolist()

这会导致 df 的单元格是 numpy 数组

df
Out[16]: 
                 A                B                C
0  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]
1  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]
2  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]
3  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]
4  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]

我想计算数据框的平均值,但它不起作用,因为每个单元格都被视为一个字符串。例如,

type(df.loc[0][0])
Out[19]: list

因此,如果我计算它的平均值,它会返回 nan

df["Average"]= df.mean(axis=1)

df
Out[21]: 
                 A                B                C  Average
0  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]      NaN
1  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]      NaN
2  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]      NaN
3  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]      NaN
4  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]      NaN

我的问题是,如何将此 df 转换回我可以使用的数值?

【问题讨论】:

  • 针对 3 个列表定义“平均值”。
  • 您是否尝试计算每个数据框元素(即每个列表)的平均值?因此有 15 个平均值?
  • @coldspeed 对于每一行,平均值是mean = sum(all_numerical_values_in_the_row)/ len (row)

标签: python pandas numpy


【解决方案1】:

您可能希望按照上述方式重组您的数据框。但是要使用您所拥有的,假设您想要数据框中每个元素的平均值,您可以尝试applymap 方法。

df.applymap(np.mean)

【讨论】:

    【解决方案2】:

    我认为将值转换为列的想法非常好,因为这样可以使用 pandas 矢量化函数:

    df1 = pd.concat([pd.DataFrame(df[c].values.tolist()) for c in df.columns], 
                     axis=1, 
                     keys=df.columns)
    df1.columns = ['{}{}'.format(i, j) for i, j in df1.columns]
    print (df1)
       A0  A1  A2  A3  A4  B0  B1  B2  B3  B4  C0  C1  C2  C3  C4
    0   0   1   2   3   4   0   1   2   3   4   0   1   2   3   4
    1   0   1   2   3   4   0   1   2   3   4   0   1   2   3   4
    2   0   1   2   3   4   0   1   2   3   4   0   1   2   3   4
    3   0   1   2   3   4   0   1   2   3   4   0   1   2   3   4
    4   0   1   2   3   4   0   1   2   3   4   0   1   2   3   4
    

    但如果需要mean的所有列表一起:

    df= pd.DataFrame(np.nan, columns =["A","B","C"], index =np.arange(5))
    df=df.astype(object)
    for c in list(df):
        for i in df.index.values:
            df.at[i, c]=np.arange(i+1).tolist()
    print (df)
                     A                B                C
    0              [0]              [0]              [0]
    1           [0, 1]           [0, 1]           [0, 1]
    2        [0, 1, 2]        [0, 1, 2]        [0, 1, 2]
    3     [0, 1, 2, 3]     [0, 1, 2, 3]     [0, 1, 2, 3]
    4  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]
    
    from itertools import chain
    from statistics import mean
    df['Average'] = [mean(list(chain.from_iterable(x))) for x in df.values.tolist()]
    print (df)
                     A                B                C  Average
    0              [0]              [0]              [0]      0.0
    1           [0, 1]           [0, 1]           [0, 1]      0.5
    2        [0, 1, 2]        [0, 1, 2]        [0, 1, 2]      1.0
    3     [0, 1, 2, 3]     [0, 1, 2, 3]     [0, 1, 2, 3]      1.5
    4  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]      2.0
    

    编辑:

    如果值是字符串:

    df= pd.DataFrame(np.nan, columns =["A","B","C"], index =np.arange(5))
    df=df.astype(object)
    for c in list(df):
        for i in df.index.values:
            df.at[i, c]=np.arange(5).tolist()
    
    df=df.astype(str)
    print (df)
                     A                B                C
    0  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]
    1  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]
    2  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]
    3  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]
    4  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]  [0, 1, 2, 3, 4]
    
    df1 = pd.concat([df[c].str.strip('[]').str.split(', ', expand=True) for c in df.columns], 
                     axis=1, 
                     keys=df.columns).astype(float)
    df1.columns = ['{}{}'.format(i, j) for i, j in df1.columns]
    df1["Average"]= df1.mean(axis=1)
    print (df1)
        A0   A1   A2   A3   A4   B0   B1   B2   B3   B4   C0   C1   C2   C3   C4  \
    0  0.0  1.0  2.0  3.0  4.0  0.0  1.0  2.0  3.0  4.0  0.0  1.0  2.0  3.0  4.0   
    1  0.0  1.0  2.0  3.0  4.0  0.0  1.0  2.0  3.0  4.0  0.0  1.0  2.0  3.0  4.0   
    2  0.0  1.0  2.0  3.0  4.0  0.0  1.0  2.0  3.0  4.0  0.0  1.0  2.0  3.0  4.0   
    3  0.0  1.0  2.0  3.0  4.0  0.0  1.0  2.0  3.0  4.0  0.0  1.0  2.0  3.0  4.0   
    4  0.0  1.0  2.0  3.0  4.0  0.0  1.0  2.0  3.0  4.0  0.0  1.0  2.0  3.0  4.0   
    
       Average  
    0      2.0  
    1      2.0  
    2      2.0  
    3      2.0  
    4      2.0  
    

    【讨论】:

    • 有趣的方法,但它似乎并没有解决问题。例如,以下代码片段在平均列上产生 nan df1["Average"]= df.mean(axis=1)
    • @LiamdeBoeuf - 如果需要最后一个解决方案,我会忘记转换为数字。现在它应该可以工作了。
    最近更新 更多