我有一个pandas数据帧。它看起来像这样:
pd.DataFrame(data=np.arange(1,10).reshape(3,3), index=['A', 'B', 'C'], columns=['A', 'B', 'C'])
但有100行和100列。
我想压扁它,所以它看起来像这样:
pd.DataFrame({'row' : ['A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C'], 'col' : ['A', 'B', 'C']*3, 'val' : np.arange(1,10)})
最有效的方法是什么?
谢谢,
杰克
答案 0 :(得分:7)
选项1
不是100%确定效率,但最简单的方法是使用 df.melt
。
df.rename_axis('row')\
.reset_index()\
.melt('row', value_name='val', var_name='col')\
.sort_values(['row', 'col'])
row col val
0 A A 1
3 A B 2
6 A C 3
1 B A 4
4 B B 5
7 B C 6
2 C A 7
5 C B 8
8 C C 9
选项2
使用 stack
-
v = df.stack().reset_index()
v.columns=['row', 'col', 'val']
v
或者,
df.stack().rename_axis(['row', 'col']).reset_index(name='val')
row col val
0 A A 1
1 A B 2
2 A C 3
3 B A 4
4 B B 5
5 B C 6
6 C A 7
7 C B 8
8 C C 9
答案 1 :(得分:3)
方法#1
NumPy方法 -
# https://stackoverflow.com/a/11146645/ @senderle
def cartesian_product(*arrays):
la = len(arrays)
dtype = np.result_type(*arrays)
arr = np.empty([len(a) for a in arrays] + [la], dtype=dtype)
for i, a in enumerate(np.ix_(*arrays)):
arr[...,i] = a
return arr.reshape(-1, la)
def flatten_dataframe(df):
c = df.columns.values.astype(str)
i = df.index.values.astype(str)
df_out = pd.DataFrame(cartesian_product(i,c),columns=[['row','col']])
df_out['val'] = df.values.ravel()
return df_out
示例运行 -
In [598]: df
Out[598]:
A B C
P 1 2 3
Q 4 5 6
R 7 8 9
In [599]: flatten_dataframe(df)
Out[599]:
row col val
0 P A 1
1 P B 2
2 P C 3
3 Q A 4
4 Q B 5
5 Q C 6
6 R A 7
7 R B 8
8 R C 9
方法#2:object
dtype dataframe
如果你对object
dtype数据框没问题,可采用另一种方法 -
def flatten_dataframe_obj(df):
c = df.columns.values.astype(str)
i = df.index.values.astype(str)
m = len(i)
n = len(c)
out = np.empty((m,n,3),dtype=object)
out[...,0] = i[:,None]
out[...,1] = c
out[...,2] = df.values
return pd.DataFrame(out.reshape(-1,3), columns=[['row','col','val']])
答案 2 :(得分:3)
这应该很快:-)
new_df=pd.DataFrame({'row':df.index.repeat(df.shape[1]),'col':df.columns.tolist()*len(df),'val':np.concatenate(df.values)})
new_df
Out[343]:
col row val
0 A A 1
1 B A 2
2 C A 3
3 A B 4
4 B B 5
5 C B 6
6 A C 7
7 B C 8
8 C C 9