python - 有效地识别发生在开始和结束时间戳之间的事件

标签 python pandas dataframe sqlite merge

我有两个数据框:

数据框一有一个时间戳、一个因素(发电量)和一个位置。

数据框二有一个事件(降雨量)、事件开始时间的时间戳、事件结束时间的时间戳和位置。

我想在第一个数据框中包含一列,表示当产生一定电量时的降雨量。

我能够创建一个小型数据框并使用以下代码运行测试:

df1 =pd.DataFrame({'factor': ['2','3','4','5','6','7'],
                   'timestamp':['2022-12-01 10:00:00','2022-12-01 10:05:00',
                                '2022-12-01 10:15:00','2022-12-01 10:20:00',
                                '2022-12-15 13:00:00','2022-12-20 06:00:00'],
                   'location':['a','b','c','d','a','d']
                   })

df2 =pd.DataFrame({'event': ['2','3','4','5','6','7'],
                   'time_start':['2022-12-01 9:00:00','2022-12-02 10:05:00',
                                 '2022-12-01 8:15:00','2022-12-01 9:20:00',
                                 '2022-12-25 10:00:00','2022-12-20 05:00:00'],
                   'time_end':['2022-12-01 16:00:00','2022-12-02 10:15:00',
                               '2022-12-01 20:15:00','2022-12-01 20:20:00',
                               '2022-12-25 13:00:00','2022-12-20 06:30:00'],
                   'location':['a','b','c','d','b','c']
                   })

df1['timestamp'] =  pd.to_datetime(df1['timestamp'])

df2['time_start'] =  pd.to_datetime(df2['time_start'])
df2['time_end'] =  pd.to_datetime(df2['time_end'])

df3 = df1.merge(df2, how='outer', on="location")
 
df3['quantity_rain'] = df3['event'].where(df3['timestamp'].between(df3['time_start'], df3['time_end']))
df3.replace(np. nan,0)

但是当我使用较大的数据帧运行代码时,内核会重新启动,因为我使用了太多的内存。

当我尝试使用 df3 = df1.merge(df2, how='outer', on="location")

合并两个数据帧时会发生这种情况

我试图找到解决这个问题的方法,我读到我应该尝试使用 SQL。我想我可以合并数据帧,将合并的数据帧转换回 pandas,然后照常进行,但我不确定该怎么做(或者即使这是处理事情的最佳方式?)。当我运行我的代码时出现错误 * sqlite://(sqlite3.OperationalError) 没有这样的表:df1

我的代码如下:

%load_ext sql
%sql sqlite://

import sqlite3

conn = sqlite3.connect('test_database')
c = conn.cursor()

# Converting dataframes to SQL tables
df1.to_sql('df1_SQL', conn, if_exists='replace', index = False)
df2.to_sql('df1_SQL', conn, if_exists='replace', index = False)

# Merging tables
%sql SELECT * FROM df1 JOIN df2 USING (location)

有没有办法用更少的 ram 和 python 来做到这一点?如果不是,sql 是可行的方法吗?我该如何修复我的代码?

最佳答案

要克服内存溢出问题,这里有一个方法。

df2 的开始和结束列创建一个间隔索引,然后通过将 df2 的索引设置为 location 以及区间指数。现在按 locationdf1 进行分组,最后使用映射系列 maptimestamp 值映射到相应的事件 concat 所有组在一起

ix = pd.IntervalIndex.from_arrays(df2['time_start'], df2['time_end'], closed='both')
event = df2.set_index(['location', ix])['event']

pd.concat([
    g.assign(event=g['timestamp'].map(event.loc[k])) 
    for k, g in df1.groupby('location', sort=False)
])

concat 之后,结果将是

  factor           timestamp location event
0      2 2022-12-01 10:00:00        a     2
4      6 2022-12-15 13:00:00        a   NaN
1      3 2022-12-01 10:05:00        b   NaN
2      4 2022-12-01 10:15:00        c     4
3      5 2022-12-01 10:20:00        d     5
5      7 2022-12-20 06:00:00        d   NaN

关于python - 有效地识别发生在开始和结束时间戳之间的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74858392/

相关文章:

Python 用 0-x 索引替换列值(对于 xgboost)

python - 将 html 数据从网站转换为 pandas 数据框

python - 将两列合并为一列

python - 在数据帧行之间进行比较以进行删除

python - 如何扩展库的装饰器?

python - 使用 pybind11 将 c++ 函数添加到现有 python 模块

javascript - 如何将javascript代码插入Jupyter

python - 加入 pandas 系列字符串

python - 如何从 Django 的复选框中获取值数组

python - 避免 Python 的栈