Python Pandas初学者:多维数据分析工作流程(groupby+agg+plot)

7
我刚开始学习pandas,并尝试学习如何处理我的多维数据。
我的数据是一个包含 ['A', 'B', 'C', 'D', 'E', 'F', 'G'] 列的大型CSV文件。这些数据描述了一些模拟结果,其中 ['A', 'B', ..., 'F'] 是模拟参数,而 'G' 是其中的一个输出(在此示例中仅存在一个输出!)。
编辑/更新:如评论中所建议的 Boud,让我们生成一些与我的数据兼容的数据:
import pandas as pd
import itertools
import numpy as np

npData = np.zeros(5000, dtype=[('A','i4'),('B','f4'),('C','i4'), ('D', 'i4'), ('E', 'f4'), ('F', 'i4'), ('G', 'f4')])

A = [0,1,2,3,6] # param A: int
B = [1000.0, 10.000] # param B: float
C = [100,150,200,250,300] # param C: int
D = [10,15,20,25,30] # param D: int
E = [0.1, 0.3] # param E: float
F = [0,1,2,3,4,5,6,7,8,9] # param F = random-seed = int -> 10 runs per scenario

# some beta-distribution parameters for randomizing the results in column "G"
aDistParams = [ (6,1),
                (5,2),
                (4,3),
                (3,4),
                (2,5),
                (1,6),
                (1,7) ]

counter = 0
for i in itertools.product(A,B,C,D,E,F):
    npData[counter]['A'] = i[0]
    npData[counter]['B'] = i[1]
    npData[counter]['C'] = i[2]
    npData[counter]['D'] = i[3]
    npData[counter]['E'] = i[4]
    npData[counter]['F'] = i[5]

    np.random.seed = i[5]
    npData[counter]['G'] = np.random.beta(a=aDistParams[i[0]][0], b=aDistParams[i[0]][1])
    counter += 1

data = pd.DataFrame(npData)
data = data.reindex(np.random.permutation(data.index)) # shuffle rows because my original data doesn't give any guarantees

由于参数 ['A','B',...,'F'] 是作为笛卡尔积(即嵌套的for循环;先验)生成的,我希望在分析输出之前使用groupby获取每个可能的“模拟场景”。
参数“F”描述了每个场景的多次运行(每个场景由“A”,“B”,...,“E”定义;假设“F”是随机种子),因此我的代码变成了:
grouped = data.groupby(['A','B','C','D','E'])
# -> every group defines one simulation scenario

grouped_agg = grouped.agg(({'G' : np.mean}))
# -> the mean of the simulation output in 'G' over 'F' is calculated for each group/scenario

现在我想做什么?

  • I: 显示这些组中每个场景参数的所有(唯一)值 -> grouped_agg给我一个元组的可迭代对象,例如每个位置0处的所有条目都为“ A”的所有值(因此使用几行python代码即可获得唯一值,但可能有一个函数可以做到这一点)

    • 更新:我的方法
    • list(set(grouped_agg.index.get_level_values('A'))) (对于“ A”感兴趣时;使用set获取唯一值;如果需要高性能,则可能不是您想要执行的操作)
    • => [0, 1, 2, 3, 6]
  • II: 生成一些低维度的图表 -> 在绘制之前需要使一些变量恒定并过滤/选择数据(因此需要步骤I)=>

    • 'B' 恒定
    • 'C' 恒定
    • 'E' 恒定
    • 'D' = x轴
    • 'G' = y轴/聚合输出
    • 'A' = 多个颜色的另一个维度= 2d-plot中的每个'A'值有一个G/y轴

    如何生成这样的图表?

    我认为,重塑我的数据是关键步骤,然后pandas绘图功能将处理它。也许实现一种形状,其中有5列(每个参数A的一个),并且对于每个索引选择+ param-A选择的相应G值就足够了,但我还没有达到那种形式。

感谢您的帮助!

(我正在使用enthought canopy中的pandas 0.12)

Sascha


请尝试在您的帖子中添加数据样本。 - Zeugma
偶尔我会处理多维数据,认为Pandas是一个很好的后处理工具,尽管我从未使用过。现在,经过相当多的努力,我必须说我没有实现我所期望的流畅工作流程。特别是从数据中取任意切片证明是困难的,这可能是由于DataFrame的二维性质固有的。也许你最好只是将数据存储在numpy数组中。 - user2379410
在我接触pandas之前,我一直使用像“groupby”(itertools)和所有numpy/scipy函数之类的东西来处理数据,没有使用专用库。我的希望是,pandas可以让我以更简洁、优雅的方式进行相同的处理,并保持一切模块化,以便将来节省“开发时间”。虽然有很多博客文章展示了pandas的潜力,但我仍然遇到了一些问题,尽管它并不那么复杂。从某种程度上说,我很高兴听到其他人也有过类似的问题。 - sascha
1个回答

2

如果我理解你的例子和所需输出,我不明白为什么需要分组。

data.A.unique()

II: 更新....

我会按照您上述概述的示例进行实现。假设我们已经像下面这样对随机种子(“F”)进行了‘G’的平均值:

data = data.groupby(['A','B','C','D','E']).agg(({'G' : np.mean})).reset_index()

首先选择具有您指定的某些常量值的B、C和E行。

df1 = data[(data['B'] == const1) & (data['C'] == const2) & (data['E'] == const3)]

现在我们想要绘制“G”作为“D”的函数,对于每个“A”的值,使用不同的颜色。
df1.set_index('D').groupby('A')['G'].plot(legend=True)

我在一些虚拟数据上测试了上述内容,结果与您描述的一样。每个“A”对应的“G”的范围以不同的颜色绘制在同一坐标系中。
III: 我不知道如何回答那么广泛的问题。
IV: 不,我认为这在这里不是一个问题。
我建议使用更简单、更小的数据集,并更加熟悉pandas。

I: 谢谢提到unique()函数。 II: 我正在处理多维数据:G = f(A,B,C,D,E,F)。我使用groupby来识别类似笛卡尔积的情况(情景=参数'A':'E'集合/常数),然后使用aggregate在此情景内计算平均值(参数'F'仍是自由度)。每个相关的图表将选择一个这些维度作为x轴(例如'D'),并嵌入到y轴中的1:n维度(例如'A'-> 5种颜色),其中'G'是值。但是因为G = f(A,B,C,D,E,F),所有其他“开放”变量必须首先被选择/设置为常数! - sascha
明白了,已经更新了上面的内容。 - Dan Allan
谢谢Dan!看起来我现在能够做我想做的事情了,而且代码看起来也很好(关于可读性和简洁性)。 还有一个微小的请求:变量“F”是每个场景中模拟运行的随机种子。因此,我首先对“G”进行分组(所有场景),然后进行聚合(问题中的第二个代码块)。使用您的代码片段在“grouped_agg.reset_index()”上将产生我想要的图。您能否在您的答案中包含这一步骤?(请随意按照您的方式进行操作;我需要reset_index()将我的索引转换为列,以便我可以在不更改的情况下使用您的代码片段) - sascha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接