数据帧使用前面的行生成变量

2024-04-28 17:12:57 发布

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

我正在尝试为我的数据集生成更多变量。我的数据存储在多个文件中,由于内存限制,使用pandas一次只能读取一个文件。每个csv文件都有一个月的数据,如下所示:


Index     Date          Sender     Recipient     Quantity     Type
------------------------------------------------------------------------
79XT     26-03-19       Adam       Tiffany       72           Box
57ZY     14-03-19       Josh       Ross          13           Snack
29UQ     19-03-19       Adam       Alex          60           Fruit
56PY     06-03-19       Lucy       Alex          29           Book
41BR     28-03-19       Josh       Steve         33           Snack

现在,我正试图根据每个发送者的历史为每一行生成更多的特性,并将这些特性连接到数据帧。例如:

Index     Date          Sender     Recipient     Quantity     Type     Days Since          Days Since         Cumulative      Quantity Increase          First Shipment   
                                                                       Previous Shipment   First Shipment     Quantity        from Previous Shipment     to This Recipient?
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
79XT     26-03-19       Adam       Tiffany       72           Box      7                   62                 1792            12                         0
57ZY     14-03-19       Josh       Ross          13           Snack    NaN                 NaN                13              NaN                        1  
29UQ     19-03-19       Adam       Alex          60           Fruit    5                   55                 1730            -7                         1
56PY     06-03-19       Lucy       Alex          29           Book     23                  32                 88              -4                         0          
41BR     28-03-19       Josh       Steve         33           Snack    14                  14                 46              20                         1

从上面所需的数据框中可以看出,新变量是根据发送方以前的观察结果生成的。生成此类特征的计算成本最低的方法是什么?我需要从我的所有每月csv文件中获取信息,以收集此类数据。有超过200000个唯一的发送者,因此读取csv文件、为每个唯一的发送者生成数据框和csv文件并将这些数据与每月的csv文件合并需要数周的时间。我知道dask和分布式dask,但我想知道是否有一种更简单的方法来实现我要做的事情


Tags: 文件csv数据dateindexnansenderquantity
2条回答

我在你的问题中看到了多个子问题

df = df.merge(df.groupby("sender").agg(first_occurence_date=("Date","min"))["sender", "first_occurrence_date"], on="sender", how="left")
# Computationally likely inefficient, and doesn't solve multiple file-issue immediately.
  • 计算效率高的解决方案: 为了快速阅读,考虑使用^ {CD1}}作为一种有效的存储格式。此操作的标准会更改,因此始终保留.csv作为备份。 您可以像这样df.to_feather("filename")编写一个文件作为feather

考虑用Pandas Docs: pd.Factorize()中描述的{{CD4}}来对字符串进行分解。我在这上面没有看到基准,但比较^ {CD5>}要比^ {CD6>}快。

<>最后,考虑建立一个小的SqLeTe3数据库,读取各个文件并存储它们。否则,获取第一个匹配项将是一件痛苦的事情,因为您必须不断覆盖旧值并多次执行计算代价高昂的操作

这里我有一个不同的方法。我会尽力的

  1. 将所有csv转换为parquet(最终看到这个answer)更改dtypes。至少
df['Date'] = df['Date'].astype("M8")

df['Date'] = pd.to_datetime(df['Date'])
  1. 由发送方重新进行分区。我假设所有拼花文件都在processed文件夹中
import dask.dataframe as dd
df = dd.read_parquet('processed')
df.to_parquet('processed2', partition_on='Sender')
  1. 现在您在每个Sender=username中都有许多文件,您应该将它们合并到一个文件中

  2. 现在可以为每个Sender=username创建函数

def fun(df):
    df = df.sort_values("Date")
    df["Day Since Prev Shipment"] = df["Date"].diff().dt.days
    df["Day Since First Shipment"](df["Date"] - df["Date"].min()).dt.days
    df["Cumulative Quantity"] = df["Quantity"].cumsum() 
    df["Quantity difference"] = df["Quantity"].diff()
    grp = df.groupby("Recipient")["Date"].min().reset_index(name="First Shipment")
    df = pd.merge(df, grp, how="left", on="Recipient")
    df["First Shipment"] = (df["Date"]==df["First Shipment"]).astype("int8")
    return df

相关问题 更多 >