通过标签对多索引数据帧进行分组以计算均值

时间:2019-01-03 12:35:20

标签: python pandas pandas-groupby

我有一个生成.csv文件的随机算法。文件内容如下:

module, coverage, timestamp
examples.monkey, 32.142857142857146, 1546513589.59586
examples.monkey, 35.714285714285715, 1546513589.609822
examples.monkey, 35.714285714285715, 1546513589.617172
...
util.container, 27.586206896551722 ,1546513594.559889
util.container, 27.586206896551722 ,1546513594.579989
util.container, 27.586206896551722 ,1546513594.598491

我有30到100个这样的文件,平均长度为几千行。

我的最终目标是为每个测量绘制一个图形,并绘制另一个图形,该图形描述给定时间所有测量的平均值。 为此,我需要计算每个时间戳的所有运行的平均值。 (当然,如果文件在某个时间戳记中没有条目,我将直接忽略它。)

到目前为止,我已读取所有.csv文件并将它们连接到新的数据框中。

allFiles = glob.glob("out/*.csv")
dfs = []

for file_ in allFiles:
    df = pd.read_csv(file_, index_col=None, header=0)
    dfs.append(df)

keys = ["Run " + str(i) for i in range(len(dfs))]
glued = pd.concat(dfs, axis=1, keys=keys)

这将导致数据帧如下所示:

             Run 0                 ...           Run 4              
            module   coverage      ...        coverage     timestamp
0  examples.monkey  32.142857      ...       32.142857  1.546514e+09
1  examples.monkey  35.714286      ...       32.142857  1.546514e+09
2  examples.monkey  35.714286      ...       32.142857  1.546514e+09
3  examples.monkey  35.714286      ...       35.714286  1.546514e+09
4  examples.monkey  35.714286      ...       35.714286  1.546514e+09

现在,我的最初想法是简单地将所有运行分组,并按轴= 1的级别= 1的模块和时间戳进行分组。像这样

grouped = glued.groupby(by=["module", "timestamp"], level=1, axis=1)

但是,这在我收到Keyerror时不起作用,原因是缺少模块和时间戳。显然,我对如何使用像这样的组合数据框有一些误解。

那么,如何最好地获取多个文件中每个模块和时间戳的平均覆盖率?

2 个答案:

答案 0 :(得分:1)

我不确定您的答案为什么不起作用,我不太熟悉多级列中的古怪。我可以提出一个应该起作用的答案。正如@jezrael在其评论中指出的那样,您可以通过添加新列而不是在行上进行串联来连接数据框。如果您这样做:

glued = pd.concat(dfs)
grouped = glued.groupby(["module", "timestamp"])
mean_by_group = grouped.mean() 

mean_by_group应该是一个数据帧,每个模块/时间戳对均具有一行,并且其中一列包含与该时间戳/模块对对应的所有条目的平均覆盖率。

答案 1 :(得分:1)

您可以通过axis=0使用concat作为默认参数,因此应将其删除,然后将第一级转换为列Run并汇总mean

allFiles = glob.glob("out/*.csv")

#instead loop list comprehension, but your solution working nice too
dfs = [pd.read_csv(fp,skipinitialspace=True) for fp in allFiles]
keys = ["Run " + str(i) for i in range(len(dfs))]

glued = pd.concat(dfs, keys=keys).reset_index(level=0).rename(columns={'level_0':'Run'})
#convert float column to datetimes 
glued['timestamp'] = pd.to_datetime(glued['timestamp'], unit='s')
#print (glued)

#specify columns what need 
grouped = glued.groupby(by=["Run","module", "timestamp"], as_index=False).mean()
#print (grouped)

grouped1 = glued.groupby(by=["module", "timestamp"], as_index=False).mean()
#print (grouped1)