Pandas 来自一系列数据帧的多索引

Pandas multiindex from series of dataframes

我有一系列具有相同结构的数据帧,它们表示一年中每个小时的模拟结果。每个模拟都包含一系列坐标 (x,y) 的结果。

每个数据帧都是从一个 csv 文件导入的,该文件仅在文件名中包含时间信息。示例:

results_YYMMDDHH.csv

包含这样的数据

   x   y         a         b
 0.0 0.0  0.318705 -0.871259
 0.1 0.0 -0.937012  0.704270
 0.1 0.1 -0.032225 -1.939544
 0.0 0.1 -1.874781 -0.033073

我想创建一个 MultiIndexed Dataframe(0 级是时间,1 级是 (x,y)),它允许我在这些数据帧之间执行各种操作,如平均值、总和、最大值等,使用重采样或 groupby 方法。对于每个时间步

生成的数据框应如下所示

                       x   y         a         b
2010-01-01 10:00     0.0 0.0  0.318705 -0.871259
                     0.1 0.0 -0.934512  0.745270
                     0.1 0.1 -0.0334525 -1.963544
                     0.0 0.1 -1.835781 -0.067573

2010-01-01 11:00     0.0 0.0  0.318705 -0.871259
                     0.1 0.0 -0.923012  0.745670
                     0.1 0.1 -0.035225 -1.963544
                     0.0 0.1 -1.835781 -0.067573
.................
.................
2010-12-01 10:00     0.0 0.0  0.318705 -0.871259
                     0.1 0.0 -0.923012  0.723270
                     0.1 0.1 -0.034225 -1.963234
                     0.0 0.1 -1.835781 -0.067233

你可以想象一年中的每个小时。我现在希望能够计算例如全年的平均值或 6 月的平均值。 还有任何其他功能,例如超过某个阈值或介于最小值和最大值之间的小时数。请记住,任何这些操作的结果都应该是一个 DataFrame。例如,每月平均值应类似于

              x   y     a     b
2010-01     0.0 0.0  0.45 -0.13
2010-02     0.1 0.0  0.55 -0.87
2010-03     0.1 0.1  0.24 -0.83
2010-04     0.0 0.1  0.11 -0.87

如何构建这个 MultiIndexed 数据框?我把它想象成一个时间序列的数据帧。

我会制作一个面板,然后使用 to_frame():

将其转换为多索引 DataFrame
In [29]: df1 = pd.DataFrame(dict(a=[0.318705,-0.937012,-0.032225,-1.874781], b=[-0.871259,0.704270,-1.939544,-0.033073]))

In [30]: df2 = pd.DataFrame(dict(a=[0.318705,-0.937012,-0.032225,-1.874781], b=[-0.871259,0.704270,-1.939544,-0.033073]))

In [31]: df1
Out[31]:
          a         b
0  0.318705 -0.871259
1 -0.937012  0.704270
2 -0.032225 -1.939544
3 -1.874781 -0.033073

In [32]: data = {datetime.datetime(2010,6,21,10,0,0): df1, datetime.datetime(2010,6,22,10,0,0): df2}

In [33]: p = pd.Panel(data)

In [34]: p.to_frame()
Out[34]:
             2010-06-21 10:00:00  2010-06-22 10:00:00
major minor
0     a                 0.318705             0.318705
      b                -0.871259            -0.871259
1     a                -0.937012            -0.937012
      b                 0.704270             0.704270
2     a                -0.032225            -0.032225
      b                -1.939544            -1.939544
3     a                -1.874781            -1.874781
      b                -0.033073            -0.033073

根据您希望如何查看数据,您可以使用 swapaxes 重新排列它:

In [35]: p.swapaxes("major", "items").to_frame()
Out[35]:
                                  0         1         2         3
major               minor
2010-06-21 10:00:00 a      0.318705 -0.937012 -0.032225 -1.874781
                    b     -0.871259  0.704270 -1.939544 -0.033073
2010-06-22 10:00:00 a      0.318705 -0.937012 -0.032225 -1.874781
                    b     -0.871259  0.704270 -1.939544 -0.033073

鉴于更充分解释的问题,这里有一个与我之前的答案不同的答案。遍历文件并将它们读入 pandas,解析日期并将其添加到数据框,然后使用 set_index 创建您的多索引。获得所有数据帧后,使用 pd.concat 组合它们:

dataframes = []
for filename in filenames:
    df = pd.read_csv(filename)
    df["datetime"] = datetime.datetime.strptime(filename[8:18], "%Y%m%d%H")
    dataframes.append(df.set_index(["datetime","x", "y"]))

combined_df = pd.concat(dataframes)