我有一个包含 2002 列和 258 行的大型 Pandas 数据框,其中每一列代表一种产品,每一行代表给定日期每种产品的销售额。
我想将其转换为 Pandas 数据框,其中包含 2002 * 258 = 516,516 行和 2 列,其中包含产品名称和销售额。我如何在 Python 中高效地执行此操作?
以下数据可以作为例子:
d = {'Product 1': [1, 2], 'Product 2': [3, 4], 'Product 3': [1, 1]}
df = pd.DataFrame(data=d)
请您参考如下方法:
我认为需要stack , 双 reset_index和 rename_axis :
df = df.stack().reset_index(level=0, drop=True).rename_axis('a').reset_index(name='b')
print (df)
a b
0 Product 1 1
1 Product 2 3
2 Product 3 1
3 Product 1 2
4 Product 2 4
5 Product 3 1
使用 numpy.tile 获得更好性能的替代方案或 numpy.repeat.html和 numpy.ravel :
df = pd.DataFrame({'a':np.tile(df.columns, len(df)), 'b':df.values.ravel()})
print (df)
a b
0 Product 1 1
1 Product 2 3
2 Product 3 1
3 Product 1 2
4 Product 2 4
5 Product 3 1
df = pd.DataFrame({'a':np.repeat(df.columns, len(df)), 'b':df.values.T.ravel()})
print (df)
a b
0 Product 1 1
1 Product 1 2
2 Product 2 3
3 Product 2 4
4 Product 3 1
5 Product 3 1
时间:
np.random.seed(145)
#[258 rows x 2002 columns]
df = pd.DataFrame(np.random.randint(100, size=(258,2002))).add_prefix('Product ')
#print (df)
In [112]: %timeit pd.DataFrame({'a':np.tile(df.columns, len(df)), 'b':df.values.ravel()})
100 loops, best of 3: 12.6 ms per loop
In [113]: %timeit pd.DataFrame({'a':np.repeat(df.columns, len(df)), 'b':df.values.T.ravel()})
100 loops, best of 3: 10.8 ms per loop
In [114]: %timeit df.reset_index().melt(id_vars='index', var_name='product', value_name='sales')
100 loops, best of 3: 18 ms per loop
In [115]: %timeit df.stack().reset_index(level=0, drop=True).rename_axis('a').reset_index(name='b')
10 loops, best of 3: 27.8 ms per loop
In [116]: %timeit df.unstack().swaplevel().sort_index()
10 loops, best of 3: 156 ms per loop
编辑:
d = {'Product 1': [1, 2], 'Product 2': [3, 4], 'Product 3': [1, 1]}
df = pd.DataFrame(data=d, index=pd.date_range('2015-01-04', periods=2))
print (df)
Product 1 Product 2 Product 3
2015-01-04 1 3 1
2015-01-05 2 4 1
df = pd.DataFrame({'a': np.repeat(df.columns, len(df)),
'b': np.tile(df.index, len(df.columns)),
'c': df.values.T.ravel()})
print (df)
a b c
0 Product 1 2015-01-04 1
1 Product 1 2015-01-05 2
2 Product 2 2015-01-04 3
3 Product 2 2015-01-05 4
4 Product 3 2015-01-04 1
5 Product 3 2015-01-05 1
