【问题标题】:summation of uneven-sized columns in pandas DataFramepandas DataFrame中不均匀大小列的总和
【发布时间】:2017-06-19 03:22:19
【问题描述】:

我有一个csv文件,内容如下:

a       b
ca  12, 20, 45
ca  18, 27
ca  30, 32, 41, 49
ny  4, 12, 12, 37, 43
ny  33
ny  8, 10, 40, 44

如何将数据作为 pandas DataFrame 读入 python 并获得每一行的平均值和总和值?

求和示例

a    b
ca  72
    45
    152
ny  108
    33
    102

【问题讨论】:

  • ab 列的分隔符是什么? tab ?
  • 这并不是一个结构良好的 CSV 文件。如果“ca”和“12”之间没有逗号,则它们不是 CSV 文件中的单独值。此外,将 pandas 用于本质上不是表格的数据通常没有意义,而您的数据不是因为您的行长度不同。

标签: python pandas group-by sum


【解决方案1】:

这并不容易,因为 csv 没有像 BrenBarn 指出的那样结构良好。

解决方案:

主要问题是您不知道列数,需要在read_csv 中添加参数names 以避免error,因此您必须使用一些常量,例如N = 20

CParserError:标记数据时出错。 C 错误:预计第 4 行中有 4 个字段,看到 5

import pandas as pd
from pandas.compat import StringIO

temp=u""" a    b
ca  12, 20, 45
ca  18, 27
ca  30, 32, 41, 49
ny  4, 12, 12, 37, 43
ny  33
ny  8, 10, 40, 44
"""
#after testing replace 'StringIO(temp)' to 'filename.csv'
N = 20
df = pd.read_csv(StringIO(temp), sep="\s+", names = range(N), skiprows = 1)
#print (df)
#create index from first column, remove all NaN columns, cast to str
df = df.set_index(0).rename_axis('a').dropna(axis=1, how='all').astype(str)
#remove all , and spaces, cast to float
df = df.apply(lambda x: x.str.strip(' ,')).astype(float)
#sum and if necessary cast to int
df1 = df.sum(axis=1).astype(int).rename('b').reset_index()
print (df1)
    a    b
0  ca   77
1  ca   45
2  ca  152
3  ny  108
4  ny   33
5  ny  102

#if need spaces
mask = df1.a != df1.a.shift()
df1.a = df1.a.where(mask,'')

print (df1)
    a    b
0  ca   77
1       45
2      152
3  ny  108
4       33
5      102

更动态的解决方案:

#get max count of space separators
data = []
with open('file.csv') as f:
    lines = f.readlines()
    for line in lines:
        data.append(len(line.split()))

#if necessary add 1
N = max(data)
print (N)
6

df = pd.read_csv('file.csv', sep="\s+",  skiprows = 1, names = range(N))
print (df)
    0    1    2    3    4     5
0  ca  12,  20,   45  NaN   NaN
1  ca  18,   27  NaN  NaN   NaN
2  ca  30,  32,  41,   49   NaN
3  ny   4,  12,  12,  37,  43.0
4  ny   33  NaN  NaN  NaN   NaN
5  ny   8,  10,  40,   44   NaN

【讨论】:

    【解决方案2】:

    设置

    import pandas as pd
    from pandas.compat import StringIO
    
    txt = """a       b
    ca  12, 20, 45
    ca  18, 27
    ca  30, 32, 41, 49
    ny  4, 12, 12, 37, 43
    ny  33
    ny  8, 10, 40, 44"""
    

    解决方案
    使用分隔符\s{2,} 读取文件,该分隔符指定两个或多个空格。这将分成ab 列。之后我们就可以处理b了。

    df = pd.read_csv(StringIO(txt), sep='\s{2,}', engine='python', index_col=0)
    df = df.b.str.split(',\s*', expand=True).astype(float) \
           .sum(1).astype(int).to_frame(name='b')
    
    print(df)
    
          b
    a      
    ca   77
    ca   45
    ca  152
    ny  108
    ny   33
    ny  102
    

    【讨论】:

      猜你喜欢
      • 2017-10-03
      • 1970-01-01
      • 2022-07-28
      • 2012-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-27
      相关资源
      最近更新 更多