【问题标题】:Merging two big Dataframes causing memory error合并两个大数据框导致内存错误
【发布时间】:2019-02-15 17:36:18
【问题描述】:

enter image description here - 表格图片 我正在尝试合并两个非常大的数据框,这给了我内存错误。这是我试图将其转换为 pandas 的 SQL 代码。

SELECT a.period, a.houseid, a.custid, a.productid, b.local_time
FROM table_a
JOIN table_b
  ON a.period = b.period
  AND a.productid = b.productid
  AND b.local_time BETWEEN a.start_time AND a.end_time

Table_aTable_b 包含数百万行。 尝试使用键连接表,并且当 table_b 的本地时间介于表 a 的开始时间和结束时间范围之间时。

DF1:

period  houseid custid prodid localtime     
20181001    1   aa  2   01/10/2018 19:04    
20181001    1   zz  9   01/10/2018 15:57    
20181001    1   zz  178 01/10/2018 13:01    
20181001    1   zz  231 02/10/2018 02:51

DF2:

PERIOD    prodid   Name Product_info    START_TIME  END_TIME

20181001    2   Xab GHI 01/10/2018 19:00    01/10/2018 19:29
20181001    2   Xab QQQ 01/10/2018 19:30    01/10/2018 19:59
20181001    2   Xab asd 01/10/2018 20:00    01/10/2018 20:29
20181001    9   S2  Angele  01/10/2018 14:00    01/10/2018 14:59
20181001    9   S2  Road    01/10/2018 15:00    01/10/2018 15:59
20181001    9   S2  Flash   01/10/2018 16:00    01/10/2018 16:59
20181001    9   S2  Simpson 01/10/2018 17:00    01/10/2018 17:29
20181001    178 T3  Chase   01/10/2018 13:00    01/10/2018 13:59
20181001    178 T3  Chase   01/10/2018 14:00    01/10/2018 14:59
20181001    178 T3  Elaine  01/10/2018 15:00    01/10/2018 15:59

DF1 的结果:

period  houseid custid   prodid    localtime Product_info Name

20181001    1   aa  2   01/10/2018 19:04    GHI     Xab
20181001    1   zz  9   01/10/2018 15:57    Road    S2
20181001    1   zz  178 01/10/2018 13:01    Chase   T3
20181001    1   zz  231 02/10/2018 02:51    None    None

请帮助我。 谢谢

【问题讨论】:

  • 开始和结束之间切片数据的大小是多少?
  • 您好,感谢您的回复。合并后,表包含 10,57,43,701 行。
  • 当然,最直接的解决方案是在开始和结束之间占用一小段时间。使用合并所需的最少列数进行切片也应该有所帮助。只要您保留唯一密钥,您就可以在此之后慢慢将它们附加回来。
  • 无论如何,是不是你的周期值不够独特?例如。如果它们是月份标签(“Jan”、“Feb”等),您最终会得到爆炸性的输出。从 2000 年到 2019 年,在两个方向上匹配所有“Jan”,比如“Jan2019”,而不是“Jan”,这可能更有意义
  • 感谢您的回答。你能告诉我合并这两个数据框的代码吗?据我所知,与 on= 合并,但有点困惑如何在从开始时间到结束时间的范围之间使用 local_time。如果可能的话,请给我看看代码。

标签: python pandas


【解决方案1】:

好的,这是我的解决方案。希望它对您的情况足够好。这是我目前的技能水平所能提供的。另一种方法是遍历一个表,并在 START_TIME 和 END_TIME 之间应用条件检查,但我决定采用这种方法,因为您说表中有数百万行。

此处的步数取决于您在 DF2 中的 START_TIME 的 bin。我的解决方案需要 2 个步骤,因为我首先在半小时 START_TIME 加入,然后在每小时 START_TIME 重复一次。

import pandas as pd
import datetime


df1 = pd.read_excel('my_sample_data.xls')
df2 = pd.read_excel('my_sample_data2.xls')

# Construct a new index column for df1 - based on half-hourly START_TIME
df1['localtime'] = pd.to_timedelta(df1.loc[:, 'localtime'])
df1['START_TIME'] = df1.loc[:,'localtime'].apply(lambda x: x.floor('1800s'))
df1['START_TIME'] = df1.loc[:,'START_TIME'].apply(lambda x: x + datetime.datetime(1970,1,1))

# Drop unneeded colums
df2 = df2.loc[:,['START_TIME', 'prodid', 'Product_info', 'Name']]
df2.set_index(['prodid', 'START_TIME'], inplace=True)

df = df1.join(df2, on=['prodid', 'START_TIME'])
# Good portion
df_done = df.loc[df['Name'].isnull() == False]
# Bad portion
df_nan = df.loc[df['Name'].isnull() == True, ['period', 'houseid', 'custid', 'prodid', 'localtime']]

# Some ranges in DF2 come with hourly frequencies. Repeat the same process above for this case
df_nan['START_TIME'] = df_nan.loc[:,'localtime'].apply(lambda x: x.floor('3600s'))
df_nan['START_TIME'] = df_nan.loc[:,'START_TIME'].apply(lambda x: x + datetime.datetime(1970,1,1))
df_nan = df_nan.join(df2, on=['prodid', 'START_TIME'])

df = pd.concat([df_done, df_nan])
df['localtime'] = df.loc[:, 'localtime'].apply(lambda x: x + datetime.datetime(1970,1,1))

>>>df
     period  houseid custid  prodid           localtime          START_TIME Product_info Name
0  20181001        1     aa       2 2018-01-10 19:04:00 2018-01-10 19:00:00          GHI  Xab
2  20181001        1     zz     178 2018-01-10 13:01:00 2018-01-10 13:00:00        Chase   T3
1  20181001        1     zz       9 2018-01-10 15:57:00 2018-01-10 15:00:00         Road   S2
3  20181001        1     zz     231 2018-02-10 02:51:00 2018-02-10 02:00:00          NaN  NaN

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-04
    • 2015-02-03
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    • 2017-08-15
    • 2020-11-10
    相关资源
    最近更新 更多