我有一张布局有点像这样的表格:
吨 | 行号 | 许多其他专栏 |
---|---|---|
1234567 | 0 | ... |
1234568 | 0 | ... |
1234569 | 0 | ... |
1234570 | 1 | ... |
1234571 | 1 | ... |
但它非常非常大。例如,原始 .dat 文件可以达到 20 GB。我将它们转换为 .h5 文件,因此它们略小一些,但仍然很大(我想大约是一半大小。)
我想添加一个表示行内时间的列,因此它会从每次时间中减去该行的第一个时间值,所以我最终得到如下结果:
吨 | 行号 | 在线时间 |
---|---|---|
1234567 | 0 | 0 |
1234568 | 0 | 1 |
1234569 | 0 | 2 |
1234570 | 1 | 0 |
1234571 | 1 | 1 |
问题是,虽然我知道一次对整个数据框执行操作要快得多,但我无法弄清楚如何在不使用 for 循环的情况下执行此操作,因为需要减去的数字取决于 linenum,并且需要很长时间。 (昨天,我在一个大约 9gb 的文件上测试了这个,处理了半个小时后我放弃了,回家了,结果今天早上发现我的电脑在一夜之间重启了,所以 jupyter 服务器不得不重启,我丢失了处理过的数据框...) 这是我目前拥有的代码的相关部分:
import pandas as pd
file = [h5 file address]
df = pd.read_hdf(file)
for linenum in pd.unique(df['linenum']):
line_df = df.loc[df['linenum'] == linenum]
first_t = int(line_df['t'].iloc[0])
df.loc[df['linenum'] == linenum, 't_adjusted'] = (df.loc[df['linenum'] == linenum, 't'] - first_t)
有没有办法不用 for 循环来做到这一点,如果没有,有没有办法让它更快?我正在尝试使用 matplotlib.pyplot.tricontourf 绘制其他列之一的图形,x 轴上是行号,y 轴上是行内时间(如果相关的话)。我可以使用另一列作为解决方法,因为它与行内时间大致成比例,但我更愿意找到一种方法来利用时间。谢谢!
编辑:另外,如果相关的话,我正在使用 Python 3.7。出于某种原因,我的程序必须在工作中运行的一些计算机仍在使用 Windows 7,所以我无法更新...
您可以使用
groupby
on'linenum'
和 thentransform
来填充每个组如果时间已经排序,您可以使用:
詹姆斯的回答更好,但如果使用顺序数据,您可以分组
linenum
然后使用.cumcount()
:import pandas as pd
df['time within line'] = df.groupby('linenum').cumcount()