【问题标题】:Pandas: Map rows from one dataframe to another based on a time conditionPandas:根据时间条件将行从一个数据帧映射到另一个数据帧
【发布时间】:2017-05-12 02:40:49
【问题描述】:

我有两个数据框,每个数据框都包含服务器上不同类型的事件。

对于数据框 A 中的每个事件(行),我想查看数据框 B 并查找在之前某个时间窗口内发生的事件,并将其 ID(其中一列中的值)复制到新列在A的当前行。

数据框 B 中有任意数量的行可以映射到数据框 A 中的一行,而 B 中的行可以映射到 A 中的多行。

到目前为止,这就是我所拥有的,但是在使用 A.set_value(...) 时出现“TypeError: len() of unsized object”

    time_frame = datetime.timedelta(hours=48)
    for index, row in A.iterrows():
        window = [pd.to_datetime(row['Time']),
                   pd.to_datetime(row['Time']) - datetime.timedelta(hours=time_frame)]
        mask = (B['Time'] < window[0]) & (B['Time'] > window[1])
        temp = B.loc(mask)
        A.set_value(index, 'related event', temp['ID'])

编辑: 这是一个简单的测试用例:

dA = {'ID' : ['A1923', 'A1922', 'A1921', 'A1920'], 'Time' : ['2017-01-23 19:16:01',
 '2017-01-22 10:52:30', '2017-01-15  16:34:22', '2017-01-05 08:31:28']}

dB = {'ID' : ['B8392', 'B8391', 'B8390', 'B8389', 'B8388', 'B8387'], 'Time' : 
['2017-01-23 11:23:55', '2017-01-22 22:47:31', '2017-01-22 09:19:07', 
'2017-01-19 01:22:18', '2017-01-15 04:38:11', '2017-01-14 18:18:51']}

A = pd.DataFrame(dA)
B = pd.DataFrame(dB)

find_relations(A, B)

理想情况下,输出是:

     ID             Time          Related
0  A1923   2017-01-23 19:16:01   B8392, B8391, B8390   
1  A1922   2017-01-22 10:52:30   B8390
2  A1921   2017-01-15 16:34:22   B8388, B8387
3  A1920   2017-01-05 08:31:28   NaN

【问题讨论】:

  • 您能否发布每个输入数据帧和预期输出的示例?
  • 我编辑了一个例子。
  • 查看 `pd.merge_asof' 并以 SO Post 为例。

标签: python pandas dataframe


【解决方案1】:

这是解决方案,问题与“相关”列的创建以及 timedelta 对象不可兼容,以及我创建临时数据框以存储来自 B 的所有相关行的方式有关。

def find_relations(A, B, time_window=48):
    A['related'] = ""
    for index, row in A.iterrows():
        window = [pd.to_datetime(row['Time']),
              pd.to_datetime(row['Time']) - DateOffset(hours=time_window)]
        mask = (pd.to_datetime(B['Time']) < window[0]) & (pd.to_datetime(B['Time']) > window[1])
        temp = B[mask]
        A.set_value(index, 'related', ','.join(list(temp['ID'])))

因此,首先我们必须通过将 A 数据框中的空列分配给空字符串对象来创建空列。然后,最好使用 pandas.tseries.offsets 中的 DateOffset 对象来创建时间窗口,而不是使用 timedelta。最后,B.loc(mask) 在语法上无效,因此将其替换为 B[mask]。

输出是:

     ID                  Time       related
0  A1923   2017-01-23 19:16:01  B8392,B8391,B8390
1  A1922   2017-01-22 10:52:30              B8391
2  A1921   2017-01-15 16:34:22        B8388,B8387
3  A1920   2017-01-05 08:31:28                     

【讨论】:

    猜你喜欢
    • 2019-10-17
    • 2022-01-20
    • 2017-04-20
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 2023-03-15
    相关资源
    最近更新 更多