给定
In [189]: dfOut[189]: IDX1 IDX2 IDX3 1983 Q4 X Y Z 1984 Q1 X.1 Y.1 Z.10 A A1 Q 10 A F NaN 110 A F NaN1 A A2 Q 20 B C 40 120 B C 2402 A A3 Q 30 A F NaN 130 A F NaN3 A A4 Q 40 B C 80 140 B C 2804 A A5 Q 50 A F NaN 150 A F NaN5 A A6 Q 60 B F 120 160 B F 320
让我们首先设置
['IDX1', 'IDX2', 'IDX3']为索引。
df = df.set_index(['IDX1', 'IDX2', 'IDX3'])
其他列具有周期性的质量;我们 希望将每4列作为一个组进行处理
。这种“作为一个组进行处理”的思想自然导致为列索引分配新的索引级别。每4列相同的值。这将是理想的:
1983 Q4 1984 Q1 W X Y Z W X Y ZIDX1 IDX2 IDX3 A A1 Q 10 A F NaN 110 A F NaN A2 Q 20 B C 240 120 B C 240 A3 Q 30 A F NaN 130 A F NaN A4 Q 40 B C 280 140 B C 280 A5 Q 50 A F NaN 150 A F NaN A6 Q 60 B F 320 160 B F 320
我们可以通过构建一个MultiIndex并将其分配给
df.columns:
columns = [col for col in df.columns if col[0] not in set(list('XYZ'))]df.columns = pd.MultiIndex.from_product([columns, list('WXYZ')])现在,可以通过调用
df.stack将列级别移入行索引来获得所需的长格式Dataframe :
df.columns.names = ['IDX4', 'ValueType']series = df.stack(['IDX4', 'ValueType'], dropna=False)
还需要注意的是,当
mangle_dupe_cols=False,重复列
X,
Y,
Z, 会被覆盖
。因此,您会丢失的数据
mangle_dupe_cols=False。例如,当您使用
mangle_dupe_cols=False最后一行的
Z值时,gets将分配给每一
Z列,而不管其周期如何。
因此,我们必须使用
mangle_dupe_cols=True,(或将其省略,因为这是默认设置),并相应地调整代码。幸运的是,这样做并不难,因为
df.columns无论如何我们都将重新分配给自定义构建的MultiIndex。
放在一起:
import numpy as npimport pandas as pddf = pd.read_table('data', sep=r's*[|]s*')df = df.set_index(['IDX1', 'IDX2', 'IDX3'])columns = [col for col in df.columns if col[0] not in set(list('XYZ'))]df.columns = pd.MultiIndex.from_product([columns, list('WXYZ')])df.columns.names = ['IDX4', 'ValueType']series = df.stack(['IDX4', 'ValueType'], dropna=False)print(series.head())产量
IDX1 IDX2 IDX3 IDX4 ValueTypeA A1 Q 1983 Q4 W 10 X A Y F Z NaN 1984 Q1 W 110dtype: object
请注意,由于我们删除了所有列级别,因此结果是一个系列。如果您想要一个具有6列的Dataframe,那么我们应该使用:
series.name = 'Value'df = series.reset_index()print(df.head())
产生
IDX1 IDX2 IDX3 IDX4 ValueType Value0 A A1 Q 1983 Q4 W 101 A A1 Q 1983 Q4 X A2 A A1 Q 1983 Q4 Y F3 A A1 Q 1983 Q4 Z NaN4 A A1 Q 1984 Q1 W 110...



