Fan*_*ang 6 python numpy dataframe pandas
如果标题有点令人困惑,请原谅我.
假设我有test.h5.以下是使用读取此文件的结果df.read_hdf('test.h5', 'testdata')
0 1 2 3 4 5 6
0 123 444 111 321 NaN NaN NaN
1 12 234 113 67 21 32 900
3 212 112 543 321 45 NaN NaN
Run Code Online (Sandbox Code Playgroud)
我想选择最后一个非Nan列.我的预期结果是这样的
0 321
1 900
2 45
Run Code Online (Sandbox Code Playgroud)
另外,我想选择除最后一个非NaN列之外的所有列.我的预期结果可能是这样的.它可能是numpy数组但我还没有任何解决方案.
0 1 2 3 4 5 6
0 123 444 111
1 12 234 113 67 21 32
3 212 112 543 321
Run Code Online (Sandbox Code Playgroud)
我在网上搜索,发现df.iloc[:, :-1]阅读所有专栏,但最后一篇,并df.iloc[:, -1]阅读最后一栏.
我使用这两个命令的当前结果如下:1.用于读取除最后一列之外的所有列
0 1 2 3 4 5
0 123 444 111 321 NaN NaN
1 12 234 113 67 21 32
3 212 112 543 321 45 NaN
Run Code Online (Sandbox Code Playgroud)
2.阅读最后一栏
0 NaN
1 900
2 Nan
Run Code Online (Sandbox Code Playgroud)
我的问题是,是否在pandas中使用任何命令或查询来解决这些问题?
感谢您的任何帮助和建议.
你可以使用sort来满足你的条件,即
ndf = df.apply(lambda x : sorted(x,key=pd.notnull),1)
Run Code Online (Sandbox Code Playgroud)
这会给
0 1 2 3 4 5 6
0 NaN NaN NaN 123.0 444.0 111.0 321.0
1 12.0 234.0 113.0 67.0 21.0 32.0 900.0
3 NaN NaN 212.0 112.0 543.0 321.0 45.0
现在您可以选择最后一列,即
ndf.iloc[:,-1]
Run Code Online (Sandbox Code Playgroud)
0 321.0 1 900.0 3 45.0 Name: 6, dtype: float64
ndf.iloc[:,:-1].apply(lambda x : sorted(x,key=pd.isnull),1)
Run Code Online (Sandbox Code Playgroud)
0 1 2 3 4 5
0 123.0 444.0 111.0 NaN NaN NaN
1 12.0 234.0 113.0 67.0 21.0 32.0
3 212.0 112.0 543.0 321.0 NaN NaN
第2部分
这是一个矢量化方式,有一些掩蔽来完成选择除最后一个非NaN列之外的所有列的第二个任务 -
idx = df.notnull().cumsum(1).idxmax(1).values.astype(int)
df_out = df.mask(idx[:,None] <= np.arange(df.shape[1]))
Run Code Online (Sandbox Code Playgroud)
这是在样本数据帧的修改/通用版本上运行的示例,在第三行中有两个NaN岛,第二行在开始时具有NaN岛 -
In [181]: df
Out[181]:
0 1 2 3 4 5 6
0 123 444.0 111.0 321 NaN NaN NaN
1 12 NaN NaN 67 21.0 32.0 900.0
3 212 NaN NaN 321 45.0 NaN NaN
In [182]: idx = df.notnull().cumsum(1).idxmax(1).values.astype(int)
In [183]: df.mask(idx[:,None] <= np.arange(df.shape[1]))
Out[183]:
0 1 2 3 4 5 6
0 123 444.0 111.0 NaN NaN NaN NaN
1 12 NaN NaN 67.0 21.0 32.0 NaN
3 212 NaN NaN 321.0 NaN NaN NaN
Run Code Online (Sandbox Code Playgroud)
第1部分
回到解决第一个案例,只需使用NumPy的高级索引 -
In [192]: df.values[np.arange(len(idx)), idx]
Out[192]: array([ 321., 900., 45.])
Run Code Online (Sandbox Code Playgroud)
选项1
df.stack().groupby(level=0).last()
0 321.0
1 900.0
3 45.0
dtype: float64
Run Code Online (Sandbox Code Playgroud)
选项2
使用apply与pd.Series.last_valid_index
# Thanks to Bharath shetty for the suggestion
df.apply(lambda x : x[x.last_valid_index()], 1)
# Old Answer
# df.apply(pd.Series.last_valid_index, 1).pipe(lambda x: df.lookup(x.index, x))
array([ 321., 900., 45.])
Run Code Online (Sandbox Code Playgroud)
选项 3
发挥创造力np.where和字典理解能力
pd.Series({df.index[i]: df.iat[i, j] for i, j in zip(*np.where(df.notnull()))})
0 321.0
1 900.0
3 45.0
dtype: float64
Run Code Online (Sandbox Code Playgroud)
选项 4
pd.DataFrame.ffill
df.ffill(1).iloc[:, -1]
0 321.0
1 900.0
3 45.0
Name: 6, dtype: float64
Run Code Online (Sandbox Code Playgroud)
解决最后一招
df.stack().groupby(level=0, group_keys=False).apply(lambda x: x.head(-1)).unstack()
0 1 2 3 4 5
0 123.0 444.0 111.0 NaN NaN NaN
1 12.0 234.0 113.0 67.0 21.0 32.0
3 212.0 112.0 543.0 321.0 NaN NaN
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
944 次 |
| 最近记录: |