我有两个数据框,如下所示:
time browncarbon blackcarbon
181.7335 0.105270 NaN
181.3809 0.166545 0.001217
181.6197 0.071581 NaN
422 rows x 3 columns
start end toc
179.9989 180.0002 155.0
180.0002 180.0016 152.0
180.0016 180.0030 151.0
1364 rows x 3 columns
第一个数据帧有一个时间列,该列每四分钟显示一次。第二个数据帧具有两个每两分钟间隔的时间列。这两个时间列都不同时开始和结束。但是,它们包含当天收集的数据。我如何制作另一个包含以下内容的数据框:
time browncarbon blackcarbon toc
422 rows X 4 columns
关于堆栈溢出有一个相关的答案,但是,仅当时间列是datetime或timestamp对象时才适用。链接为:How to join two dataframes for which column values are within a certain range?
附录1:封装到时间行之一中的多个开始行和结束行也应与一个toc行相对应,就像现在一样,但是,它应该是多个toc行的平均值,即目前情况并非如此。
答案 0 :(得分:0)
我们创建了一个人工键列来进行outer merge
来获取笛卡尔积(行之间的所有匹配项)。然后,我们用.query
过滤时间在范围之间的所有行。
注释:我编辑了一行的值,以便我们可以进行匹配(请参见底部示例数据帧中的第0行)
df1.assign(key=1).merge(df2.assign(key=1), on='key', how='outer')\
.query('(time >= start) & (time <= end)')\
.drop(['key', 'start', 'end'], axis=1)
输出
time browncarbon blackcarbon toc
1 180.0008 0.10527 NaN 152.0
使用的示例数据框:
df1
:
time browncarbon blackcarbon
0 180.0008 0.105270 NaN
1 181.3809 0.166545 0.001217
2 181.6197 0.071581 NaN
df2
:
start end toc
0 179.9989 180.0002 155.0
1 180.0002 180.0016 152.0
2 180.0016 180.0030 151.0
答案 1 :(得分:0)
由于开始和结束间隔是互斥的,因此我们可以在df2中创建新列,使其包含floor(start)和floor(end)范围内的所有整数值。稍后,在df1中添加另一列作为floor(time),然后在df1和df2上进行左外部联接。我认为应该这样做,除非您可能需要删除nan值和多余的列。如果您将csv文件发送给我,我也许可以向您发送脚本。希望我回答了你的问题。
答案 2 :(得分:0)
您的第二个数据帧太短,因此不会反映有意义的合并。所以我做了一点修改:
df2 = pd.DataFrame({'start': [179.9989, 180.0002, 180.0016, 181.3, 181.5, 181.7],
'end': [180.0002, 180.0016, 180.003, 181.5, 185.7, 181.8],
'toc': [155.0, 152.0, 151.0, 150.0, 149.0, 148.0]})
df1['Rank'] = np.arange(len(df1))
new_df = pd.merge_asof(df1.sort_values('time'), df2,
left_on='time',
right_on='start')
给您
time browncarbon blackcarbon Rank start end toc
0 181.3809 0.166545 0.001217 1 181.3 181.5 150.0
1 181.6197 0.071581 NaN 2 181.5 185.7 149.0
2 181.7335 0.105270 NaN 0 181.7 181.8 148.0
,您可以在sort_values
上添加多余的列和Rank
。例如:
new_df.sort_values('Rank').drop(['Rank','start','end'], axis=1)
给予:
time browncarbon blackcarbon toc
2 181.7335 0.105270 NaN 148.0
0 181.3809 0.166545 0.001217 150.0
1 181.6197 0.071581 NaN 149.0
答案 3 :(得分:0)
也许您可以将列转换为时间戳,然后在您链接的其他问题中使用答案
from pandas import Timestamp
from dateutil.relativedelta import relativedelta as rd
def to_timestamp(x):
return Timestamp(2000, 1, 1) + rd(days=x)
df['start_time'] = df.start.apply(to_timestamp)
df['end_time'] = df.end.apply(to_timestamp)