python - Pandas 在数据帧的每一列的第一个有效索引之前和最后一个有效索引之后下降
问题描述
我有一个这样的数据框:
df = pd.DataFrame({'timestamp':pd.date_range('2018-01-01', '2018-01-02', freq='2h', closed='right'),'col1':[np.nan, np.nan, np.nan, 1,2,3,4,5,6,7,8,np.nan], 'col2':[np.nan, np.nan, 0, 1,2,3,4,5,np.nan,np.nan,np.nan,np.nan], 'col3':[np.nan, -1, 0, 1,2,3,4,5,6,7,8,9], 'col4':[-2, -1, 0, 1,2,3,4,np.nan,np.nan,np.nan,np.nan,np.nan]
})[['timestamp', 'col1', 'col2', 'col3', 'col4']]
看起来像这样:
timestamp col1 col2 col3 col4
0 2018-01-01 02:00:00 NaN NaN NaN -2.0
1 2018-01-01 04:00:00 NaN NaN -1.0 -1.0
2 2018-01-01 06:00:00 NaN 0.0 NaN 0.0
3 2018-01-01 08:00:00 1.0 1.0 1.0 1.0
4 2018-01-01 10:00:00 2.0 NaN 2.0 2.0
5 2018-01-01 12:00:00 3.0 3.0 NaN 3.0
6 2018-01-01 14:00:00 NaN 4.0 4.0 4.0
7 2018-01-01 16:00:00 5.0 NaN 5.0 NaN
8 2018-01-01 18:00:00 6.0 NaN 6.0 NaN
9 2018-01-01 20:00:00 7.0 NaN 7.0 NaN
10 2018-01-01 22:00:00 8.0 NaN 8.0 NaN
11 2018-01-02 00:00:00 NaN NaN 9.0 NaN
现在,我想在第一个有效索引之前和最后一个有效索引之后找到一种有效且 Pythonic 的切断方式(对于每一列!不计算时间戳)。在这个例子中,我有 4 列,但实际上我有更多,大约 600 列。我正在寻找一种对第一个有效索引之前的所有 NaN 值和最后一个有效索引之后的所有 NaN 值进行切割的方法。
我猜一种方法是循环遍历..但是有更好的方法吗?这种方式必须是有效的。我尝试使用熔化“取消旋转”数据框,但这并没有帮助。
很明显的一点是,每列在切割后会有不同的行数。因此,我希望结果是具有时间戳和相关列的数据帧列表(每列一个)。例如:
timestamp col1
3 2018-01-01 08:00:00 1.0
4 2018-01-01 10:00:00 2.0
5 2018-01-01 12:00:00 3.0
6 2018-01-01 14:00:00 NaN
7 2018-01-01 16:00:00 5.0
8 2018-01-01 18:00:00 6.0
9 2018-01-01 20:00:00 7.0
10 2018-01-01 22:00:00 8.0
我的尝试
我试过这样:
final = []
columns = [c for c in df if c !='timestamp']
for col in columns:
first = df.loc[:, col].first_valid_index()
last = df.loc[:, col].last_valid_index()
final.append(df.loc[:, ['timestamp', col]].iloc[first:last+1, :])
解决方案
您可以使用函数式编程的强大功能并将函数应用于每一列。这可能会加快速度。此外,当您timestamps
看起来排序时,您可以将它们用作 Datarame 的索引。
df.set_index('timestamp', inplace=True)
final = []
def func(col):
first = col.first_valid_index()
last = col.last_valid_index()
final.append(col.loc[first:last])
return
df.apply(func)
此外,您可以将所有内容压缩在一个衬里中:
final = []
df.apply(lambda col: final.append(col.loc[col.first_valid_index() : col.last_valid_index()]))
推荐阅读
- r - 读入满足 R 中特定要求的表
- javascript - 无法验证在客户端使用 Javascript 创建的服务器端的 RSA 签名
- url - 将 /home/opencart/public_html/opencart 更改为 localhost URL(将服务器 URL 更改为 localhost URL)
- javascript - 在 .vue 组件中合并多个数据
- python - 为什么执行列表推导比在 for 循环中使用 += 需要更长的时间?
- javascript - jinja2.exceptions.TemplateSyntaxError:预期的令牌',',得到'静态'
- java - 与 just_a_name.cer 和 just_a_name.p7b 的 SSL 连接以导入到 Java 中的 cacerts 失败
- docker - 在 DigitalOcean 液滴上托管的基于 Debian 的 Docker 映像上的 apt-get 更新失败
- mysql - MySQL - 首先按字母顺序排列字段,然后按小数顺序排列
- flask - 为互联网打开端口 5000 不适用于谷歌云计算引擎实例