我有一个包含大量NaN的大数据框,我想将它存储到一个较小的数据框中,该数据框存储所有索引和非NaN非零值的值。
dff = pd.DataFrame(np.random.randn(4,3), columns=list('ABC'))
dff.iloc[0:2,0] = np.nan
dff.iloc[2,2] = np.nan
dff.iloc[1:4,1] = 0
数据框可能如下所示:
A B C
0 NaN -2.268882 0.337074
1 NaN 0.000000 1.340350
2 -1.526945 0.000000 NaN
3 -1.223816 0.000000 -2.185926
我想要一个如下所示的数据框:
0 B -2.268882
0 C 0.337074
1 C 1.340350
2 A -1.526945
3 A -1.223816
4 C -2.185926
我怎样才能快速完成,因为我有一个相对较大的数据框架,成千上万......
非常感谢!
答案 0 :(得分:2)
将0
替换为np.nan
,将.stack()
替换为(see docs)。
如果在np.nan
之后您rows
中的所有.replace()
值都有可能,那么您可以在.dropna(how='all')
之前执行.stack()
以减少行数转动。如果这可以适用于columns
做`.dropna(how ='all',axis = 1)。
df.replace(0, np.nan).stack()
0 B -2.268882
C 0.337074
1 C 1.340350
2 A -1.526945
3 A -1.223816
C -2.185926
根据需要与.reset_index()
合并。
从Series
MultiIndex
使用.loc[(level_0, level_1)]
df.loc[(0, 'B')] = -2.268882
docs中切片等的详细信息。
答案 1 :(得分:0)
我想出了一些有点难看的实现方法,但是嘿,它有效。但是这个解决方案的索引从0开始,并没有保留' A' B' C' C' C'如你的问题,如果重要的话。
import pandas as pd
import numpy as np
dff = pd.DataFrame(np.random.randn(4,3), columns=list('ABC'))
dff.iloc[0:2,0] = np.nan
dff.iloc[2,2] = np.nan
dff.iloc[1:4,1] = 0
dff.iloc[2,1] = np.nan
# mask to do logical and for two lists
mask = lambda y,z: list(map(lambda x: x[0] and x[1], zip(y,z)))
# create new frame
new_df = pd.DataFrame()
types = []
vals = []
# iterate over columns
for col in dff.columns:
# get the non empty and non zero values from current column
data = dff[col][mask(dff[col].notnull(), dff[col] != 0)]
# add corresponding original column name
types.extend([col for x in range(len(data))])
vals.extend(data)
# populate the dataframe
new_df['Types'] = pd.Series(types)
new_df['Vals'] = pd.Series(vals)
print(new_df)
# A B C
#0 NaN -1.167975 -1.362128
#1 NaN 0.000000 1.388611
#2 1.482621 NaN NaN
#3 -1.108279 0.000000 -1.454491
# Types Vals
#0 A 1.482621
#1 A -1.108279
#2 B -1.167975
#3 C -1.362128
#4 C 1.388611
#5 C -1.454491
我期待更多pandas/python
喜欢回答自己!