use*_*035 4 python nan dataframe pandas
我有一个 Pandas Dataframe,每行至少有 4 个非 NaN 值,但位于不同的列:
Index Col1 Col2 Col3 Col4 Col5 Col6 Col7 Col8
1991-12-31 100.000 100.000 100.000 89.123 NaN NaN NaN NaN
1992-01-31 98.300 101.530 100.000 NaN 92.342 NaN NaN NaN
1992-02-29 NaN 100.230 98.713 97.602 NaN NaN NaN NaN
1992-03-31 NaN NaN 102.060 93.473 98.123 NaN NaN NaN
1992-04-30 NaN 102.205 107.755 94.529 94.529 NaN NaN NaN
Run Code Online (Sandbox Code Playgroud)
(我只显示前 8 列)我想将其转换为每行 4 列的数据框。这些行应仅包含该日期的前四个(从左到右读取)非 NaN 值。
每行的顺序很重要。
方法#1:这是一个 NumPy 解决方案,使用justify
-
pd.DataFrame(justify(df.values, invalid_val=np.nan, axis=1, side='left')[:,:4])
Run Code Online (Sandbox Code Playgroud)
样本运行 -
In [211]: df
Out[211]:
Col1 Col2 Col3 Col4 Col5 Col6 Col7 Col8
Index
1991-12-31 100.0 100.000 100.000 89.123 NaN NaN NaN NaN
1992-01-31 98.3 101.530 100.000 NaN 92.342 NaN NaN NaN
1992-02-29 NaN 100.230 98.713 97.602 NaN NaN NaN NaN
1992-03-31 NaN NaN 102.060 93.473 98.123 NaN NaN NaN
1992-04-30 NaN 102.205 107.755 94.529 94.529 NaN NaN NaN
In [212]: pd.DataFrame(justify(df.values, invalid_val=np.nan, axis=1, side='left')[:,:4])
Out[212]:
0 1 2 3
0 100.000 100.000 100.000 89.123
1 98.300 101.530 100.000 92.342
2 100.230 98.713 97.602 NaN
3 102.060 93.473 98.123 NaN
4 102.205 107.755 94.529 94.529
Run Code Online (Sandbox Code Playgroud)
方法#2:使用掩模的定制功能 -
def app2(df, N=4):
a = df.values
out = np.empty_like(a)
mask = df.isnull().values
mask_sorted = np.sort(mask,1)
out[~mask_sorted] = a[~mask]
return pd.DataFrame(out[:,:N])
Run Code Online (Sandbox Code Playgroud)
保持秩序的工作解决方案的运行时测试 -
# Using df from posted question to recreate a bigger one :
df = df.set_index('Index')
df = pd.concat([df] * 10000, ignore_index=1)
In [298]: %timeit app2(df)
100 loops, best of 3: 4.06 ms per loop
In [299]: %timeit pd.DataFrame(justify(df.values, invalid_val=np.nan, axis=1, side='left')[:,:4])
100 loops, best of 3: 4.78 ms per loop
In [300]: %timeit df.apply(sorted, key=np.isnan, axis=1).iloc[:, :4]
1 loop, best of 3: 4.05 s per loop
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1687 次 |
最近记录: |