Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 合并数据帧会占用太多内存_Python_Pandas_Memory_Dask - Fatal编程技术网

Python 合并数据帧会占用太多内存

Python 合并数据帧会占用太多内存,python,pandas,memory,dask,Python,Pandas,Memory,Dask,我正在做我所学课程的最后一个项目,为此,我试图复制,但他使用了一个函数来获取滞后功能,这对我来说占用了太多的内存。这是他的密码: def lag_feature(df, lags, col): tmp = df[['date_block_num','shop_id','item_id',col]] for i in lags: shifted = tmp.copy() shifted.columns = ['date_block_num','sho

我正在做我所学课程的最后一个项目,为此,我试图复制,但他使用了一个函数来获取滞后功能,这对我来说占用了太多的内存。这是他的密码:

def lag_feature(df, lags, col):
    tmp = df[['date_block_num','shop_id','item_id',col]]
    for i in lags:
        shifted = tmp.copy()
        shifted.columns = ['date_block_num','shop_id','item_id', col+'_lag_'+str(i)]
        shifted['date_block_num'] += i
        df = pd.merge(df, shifted, on=['date_block_num','shop_id','item_id'], how='left')
    return df
在未能使用他的代码运行后,我做了一些轻微的修改,试图减少内存使用,我开始使用google colab,因为它比我的笔记本电脑内存多,所以下面是我的代码:

def lag_feature(df, lags, col):
  df = dd.from_pandas(df, chunksize=1000)
  tmp = df[['date_block_num','shop_id','item_id',col]]
  for i in lags:
    shifted = tmp[tmp.date_block_num + i <= 34].copy()
    shifted.columns = ['date_block_num','shop_id','item_id', col+'_lag_'+str(i)]
    shifted['date_block_num'] += i
    df = dd.merge(df, shifted, on=['date_block_num','shop_id','item_id'], how='left')
  return df.compute()
有没有办法减少我的内存使用?这是我的数据帧:

Int64Index: 2829445 entries, 0 to 3134798
Data columns (total 8 columns):
date                object
date_block_num      int8
item_cnt_day        float16
item_id             int16
item_price          float16
shop_id             int8
item_cnt_month      float16
item_category_id    int8
dtypes: float16(3), int16(1), int8(3), object(1)
memory usage: 152.9+ MB
         date  date_block_num  item_cnt_day  item_id  item_price  shop_id  \
0  14.09.2013               8           1.0     2848        99.0       24   
1  14.09.2013               8           1.0     2848        99.0       24   
2  14.09.2013               8           1.0     2848        99.0       24   
3  01.09.2013               8           1.0     2848        99.0       24   
4  01.09.2013               8           1.0     2848        99.0       24   

   item_cnt_month  item_category_id
0             2.0                30
1             2.0                30 
2             2.0                30 
3             2.0                30 
4             2.0                30
只是为了添加更多信息,“date\u block\u num”列保留了一个数字,用于标识该功能发生的月份,我试图做的是将上个月的一些数据放入该行。因此,如果我的滞后时间为1,则意味着我希望获取数据框中每个产品一个月前的数据,并将其添加到另一个名为“feature_lag_1”的列中。例如,使用此数据帧:

Int64Index: 2829445 entries, 0 to 3134798
Data columns (total 8 columns):
date                object
date_block_num      int8
item_cnt_day        float16
item_id             int16
item_price          float16
shop_id             int8
item_cnt_month      float16
item_category_id    int8
dtypes: float16(3), int16(1), int8(3), object(1)
memory usage: 152.9+ MB
         date  date_block_num  item_cnt_day  item_id  item_price  shop_id  \
0  14.09.2013               8           1.0     2848        99.0       24   
1  14.09.2013               8           1.0     2848        99.0       24   
2  14.09.2013               8           1.0     2848        99.0       24   
3  01.09.2013               8           1.0     2848        99.0       24   
4  01.09.2013               8           1.0     2848        99.0       24   

   item_cnt_month  item_category_id
0             2.0                30
1             2.0                30 
2             2.0                30 
3             2.0                30 
4             2.0                30
这个函数调用:

sales_train = lag_feature(sales_train, [1], 'item_cnt_month')
我想要这个输出:

         date  date_block_num  item_cnt_day  item_id  item_price  shop_id  \
0  14.09.2013               8           1.0     2848        99.0       24   
1  14.09.2013               8           1.0     2848        99.0       24   
2  14.09.2013               8           1.0     2848        99.0       24   
3  01.09.2013               8           1.0     2848        99.0       24   
4  01.09.2013               8           1.0     2848        99.0       24   

   item_cnt_month  item_category_id  item_cnt_month_lag_1  
0             2.0                30                   3.0  
1             2.0                30                   3.0  
2             2.0                30                   3.0  
3             2.0                30                   3.0  
4             2.0                30                   3.0  
调用
df.compute()


相反,更常见的做法是不调用compute,而是最终计算某种适合内存的聚合,或者,如果需要完整的数据帧,则使用类似于
df.to_parquet()

的东西将其写入磁盘。该函数可以在Python 3.6+中重写如下(需要先对数据帧进行预排序):


您面临的内存问题可能是由于具有同一数据帧的多个(子)副本。在pandas中不需要这样做,正如其他人指出的那样,
.shift
函数可以实现您需要的功能

首先创建一个pandas数据框架,它有两个商店,即24和25

df = pd.DataFrame({'shop_id':[24, 24, 24, 24, 24, 25, 25, 25, 25, 25],
                   'item_id': [2000, 2000, 2000, 3000, 3000, 1000, 1000, 1000, 1000, 1000], 
                   'date_block_num': [7, 8, 9, 7, 8, 5, 6, 7, 8, 9], 
                   'item_cnt_month': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]})

+-------+-------+--------------+--------------+
|shop_id|item_id|date_block_num|item_cnt_month|
+-------+-------+--------------+--------------+
|     24|   2000|             7|             1|
|     24|   2000|             8|             2|
|     24|   2000|             9|             3|
|     24|   3000|             7|             4|
|     24|   3000|             8|             5|
|     25|   1000|             5|             6|
|     25|   1000|             6|             7|
|     25|   1000|             7|             8|
|     25|   1000|             8|             9|
|     25|   1000|             9|            10|
+-------+-------+--------------+--------------+
在24号店,有2000号和3000号商品

日期块7中有1项2000计数,日期块8中有2项计数,以此类推

目标是为该商店的该商品创建一个item_cnt_month lag列,其值为item_cnt_month n个月前

要创建滞后特征,可以使用以下功能

def lag_features(df, lags, group_cols, shift_col):
    """
    Arguments:
        df (pd.DataFrame)
        lags (list((int)): the number of months to lag by
        group_cols (list(str)): the list of columns that need to be the merged key
        shift_col (str): the column name that is to be shifted by
    """

    for lag in lags:
        new_col = '{0}_lag_{1}'.format(shift_col, lag)
        df[new_col] = df.groupby(group_cols)[shift_col].shift(lag)

    return df
打电话

lags = [1, 2]
group_cols = ['shop_id', 'item_id']
shift_col = 'item_cnt_month'
order_col = 'date_block_num' 

df = df.sort_values(by=group_cols+[order_col], ascending=True)
df = lag_features(df, lags, group_cols, shift_col)
结果是:

+-------+-------+--------------+--------------+--------------------+--------------------+
|shop_id|item_id|date_block_num|item_cnt_month|item_cnt_month_lag_1|item_cnt_month_lag_2|
+-------+-------+--------------+--------------+--------------------+--------------------+
|     24|   2000|             7|             1|                 NaN|                 NaN|
|     24|   2000|             8|             2|                 1.0|                 NaN|
|     24|   2000|             9|             3|                 2.0|                 1.0|
|     24|   3000|             7|             4|                 NaN|                 NaN|
|     24|   3000|             8|             5|                 4.0|                 NaN|
|     25|   1000|             5|             6|                 NaN|                 NaN|
|     25|   1000|             6|             7|                 6.0|                 NaN|
|     25|   1000|             7|             8|                 7.0|                 6.0|
|     25|   1000|             8|             9|                 8.0|                 7.0|
|     25|   1000|             9|            10|                 9.0|                 8.0|
+-------+-------+--------------+--------------+--------------------+--------------------+

请注意,由于没有显式联接,因此需要使用
.sort\u值(所有键列和日期列)

为数据帧正确排序。能否提供一个包含数据和预期输出的值?我不明白你为什么要在这里合并。您可能只需要
.shift
或者简单地使用索引将新系列添加为一列,并在索引上自动对齐即可。现在我只是在等待Mrokilin的答案是否有效,一旦完成处理,我可以发布更多详细信息,但如果有效,我可以尝试更好地描述它。只是我的笔记本仍在处理中。我做了一些更改,希望能有所帮助,我会尽快添加示例。@ALollz,如果这有助于您使用Jupyter笔记本进行此操作,我已经添加了更多信息?这仍然会占用太多内存,耗时太长,没有其他替代方法吗?最后一个数据帧不应该使用那么多内存,只需要多出一列