pandas中类似SQL的连接

2024-06-28 15:42:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个数据帧,第一个是表单(注意日期是datetime对象):

df = DataFrame('key': [0,1,2,3,4,5],
               'date': [date0,date1, date2, date3, date4, date5],
               'value': [0,10,20,30,40,50])

第二种是:

df2 = DataFrame('key': [0,1,2,3,4,5],
                'valid_from': [date0, date0, date0, date3, date3, date3],
                'valid_to': [date2, date2, date2, date5, date5, date5],
                'value': [0, 100, 200, 300, 400, 500])

我正在尝试有效地加入密钥匹配的位置,并且日期介于有效起始和有效结束之间。我想到的是:

def map_keys(df2, key, date):
    value = df2[df2['key'] == key & 
        df2['valid_from'] <= date & 
        df2['valid_to'] >= date]['value'].values[0]
    return value

keys = df['key'].values
dates = df['date'].values
keys_dates = zip(keys, dates)

values = []
for key_date in keys_dates:
    value = map_keys(df2, key_date[0], key_date[1])
    values.append(value)

df['joined_value'] = values

虽然这似乎完成了工作,但感觉不是一个特别优雅的解决方案。我想知道是否有人有更好的主意加入这样的行列。

谢谢你的帮助-非常感谢。


Tags: keyfromdataframedfdatevaluekeysdates
1条回答
网友
1楼 · 发布于 2024-06-28 15:42:37

目前,您可以使用内置的^{}boolean indexing在几个步骤中完成此操作。

merged = df.merge(df2, on='key')

valid = (merged.date >= merged.valid_from) & \
        (merged.date <= merged.valid_to)

df['joined_value'] = merged[valid].value_y

(注意:df2value列在合并后作为value_y访问,因为它与df中同名的列冲突,并且默认的合并冲突后缀分别是_x, _y用于左帧和右帧。)

下面是一个例子,使用不同的设置来显示如何处理无效日期。

n = 8
dates = pd.date_range('1/1/2013', freq='D', periods=n)
df = DataFrame({'key': np.arange(n),
                'date': dates,
                'value': np.arange(n) * 10})
df2 = DataFrame({'key': np.arange(n),
                 'valid_from': dates[[1,1,1,1,5,5,5,5]],
                 'valid_to': dates[[4,4,4,4,6,6,6,6]],
                 'value': np.arange(n) * 100})

输入df2

   key          valid_from            valid_to  value
0    0 2013-01-02 00:00:00 2013-01-05 00:00:00      0
1    1 2013-01-02 00:00:00 2013-01-05 00:00:00    100
2    2 2013-01-02 00:00:00 2013-01-05 00:00:00    200
3    3 2013-01-02 00:00:00 2013-01-05 00:00:00    300
4    4 2013-01-06 00:00:00 2013-01-07 00:00:00    400
5    5 2013-01-06 00:00:00 2013-01-07 00:00:00    500
6    6 2013-01-06 00:00:00 2013-01-07 00:00:00    600
7    7 2013-01-06 00:00:00 2013-01-07 00:00:00    700

中间帧merged

                 date  key  value_x          valid_from            valid_to  value_y
0 2013-01-01 00:00:00    0        0 2013-01-02 00:00:00 2013-01-05 00:00:00        0
1 2013-01-02 00:00:00    1       10 2013-01-02 00:00:00 2013-01-05 00:00:00      100
2 2013-01-03 00:00:00    2       20 2013-01-02 00:00:00 2013-01-05 00:00:00      200
3 2013-01-04 00:00:00    3       30 2013-01-02 00:00:00 2013-01-05 00:00:00      300
4 2013-01-05 00:00:00    4       40 2013-01-06 00:00:00 2013-01-07 00:00:00      400
5 2013-01-06 00:00:00    5       50 2013-01-06 00:00:00 2013-01-07 00:00:00      500
6 2013-01-07 00:00:00    6       60 2013-01-06 00:00:00 2013-01-07 00:00:00      600
7 2013-01-08 00:00:00    7       70 2013-01-06 00:00:00 2013-01-07 00:00:00      700

添加列joined_valuedf的最终值:

                 date  key  value  joined_value
0 2013-01-01 00:00:00    0      0           NaN
1 2013-01-02 00:00:00    1     10           100
2 2013-01-03 00:00:00    2     20           200
3 2013-01-04 00:00:00    3     30           300
4 2013-01-05 00:00:00    4     40           NaN
5 2013-01-06 00:00:00    5     50           500
6 2013-01-07 00:00:00    6     60           600
7 2013-01-08 00:00:00    7     70           NaN

相关问题 更多 >