python - DataFrame 中的最后一个匹配值(Python)

标签 python pandas dataframe

我有一个非常大的 df 正在尝试处理,但到目前为止我发现的唯一方法是使用 for 循环,这花费的时间太长了。我知道这是可能的,但不确定如何希望有人能提供帮助。假设我有以下 df:

Date       ID   Name Old_Value New_Value
2018-01-01 101  Bob  10.0      12.0
2018-01-01 102  Tim  9.0       14.0

..... 15 mil rows

我需要找到一种获取 Bob 的 New_Value 并将其用作他的下一个 Old_Value 的方法,以便 df 看起来如下所示:

Date       ID   Name Old_Value New_Value
2018-01-01 101  Bob  10.0      12.0
2018-01-01 102  Tim  9.0       14.0
2018-02-01 101  Bob  12.0      9.0
2018-02-14 101  Bob  9.0       7.0
2018-02-14 102  Tim  14.0      19.0
2018-02-21 101  Bob  7.00      6.0
2018-02-21 102  Tim  19.0      16.0
2018-02-23 102  Tim  16.0      14.0

问题是在知道每个 ID 的旧值之前无法计算新值,并且日期必须在整个 df 中按升序排列。因此,在第三行中将 9.0 作为 New_Value 返回的计算依赖于更新后的 Old_Value(从第一行中的 New_Value 返回 12.0)。

有些 ID 在 df 中出现的频率高于其他 ID,并且它们出现的时间没有固定的顺序。数据框有超过 100,000 个唯一 ID,使用 for 循环不是一个可行的解决方案,因为运行时间长达数千小时。

*更新:感谢您到目前为止的回答,我添加了更多信息以使其更加清晰。

最佳答案

我不确定我是否完全理解您的问题,但也许这个适用于按时排序的数据框的解决方案可以提供帮助:

首先我模仿了你的数据库(这将花费大部分时间):

import pandas as pd
import numpy as np
import time

df_len = 15*10**6
user_size = 100000

now = int(time.time())
df = pd.DataFrame(index = range(df_len))
df['time_delta'] = np.random.choice(60, df_len)
df['time_delta_sum'] = df.time_delta.cumsum()
df['time_sec']= now - df.time_delta_sum
df['user_id'] = np.random.choice(user_size, df_len)
df['New_Value'] = np.random.choice(80, df_len)
df.sort_values(['user_id', 'time_sec'], inplace = True)

df['Old_Value'] = None
df['Old_Value'].iloc[1:] = df.New_Value.iloc[:-1].values
df['Old_Value'].iloc[0] = np.random.choice(80)

df.sort_values(['time_sec'], inplace = True)

df['date_time'] = df['time_sec'].apply(time.ctime)
df = df[['date_time', 'user_id', 'Old_Value', 'New_Value']].reset_index(drop = True)

这条尾部看起来像:

df.tail() =
                         date_time  user_id Old_Value  New_Value
14999995  Thu May 17 01:14:14 2018    33790        42         23
14999996  Thu May 17 01:14:36 2018    44252        58         75
14999997  Thu May 17 01:15:18 2018    86755         7         45
14999998  Thu May 17 01:15:44 2018    31874        24         72
14999999  Thu May 17 01:16:20 2018    94365        27         29

应该做更新的函数

def Append_To_Df(user_id, new_value):
    global df
    old_value = df.loc[df.user_id == user_id, 'New_Value'].iloc[-1]
    df = df.append(pd.DataFrame([[time.ctime(),user_id,old_value,new_value]], columns = df.columns, index = [len(df)]))

然后使用用户 ID 和该用户的新值调用此函数

user_id = 3357
new_value = 35

Append_To_Df(user_id, new_value)

数据帧的尾部将如下所示:

df.tail() =
                         date_time  user_id Old_Value  New_Value
14999996  Thu May 17 01:14:36 2018    44252        58         75
14999997  Thu May 17 01:15:18 2018    86755         7         45
14999998  Thu May 17 01:15:44 2018    31874        24         72
14999999  Thu May 17 01:16:20 2018    94365        27         29
15000000  Thu May 17 01:18:34 2018     3357        37         35

请注意,这仅在用户已在数据库中时才有效。

关于python - DataFrame 中的最后一个匹配值(Python),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50379490/

相关文章:

python - 两个分类变量的笛卡尔积

python - 将 pandas DataFrame 列拆分为可变数量的列

r - 如何从 R 中的数据框中删除带有 inf 的行

python - 如何使用 model() 删除项目后清理困惑

python - 矩阵从 C 函数到 Python

python - Pandas 数据帧 : fastest way of updating multiple rows based on a list of dictionaries

python - 使用另一列内的列名称 reshape 数据框

python - ubuntu pygame 窗口没有出现在蛇中

python - 如何以交互方式将点绘制到 PyQT 中 QLabel 上的像素图上

Python - 根据列值将数据框拆分为多个数据框并用这些值命名它们