在循环中合并数据帧-熊猫很慢

时间:2019-02-27 12:23:36

标签: python pandas

我正在使用函数segmentMatch,在其中我要发送两个数据帧。我正在通过一个数据帧使用for循环,并且在与具有循环变量的另一个数据帧合并之前需要检查一些条件。它给了我一个完美的答案,但是因为两个数据帧都太大,所以速度太慢。

有什么办法可以提高速度。

def segmentMatch(self, df, df_program):

    df_result = []
    for i, rview in df.iterrows():
        df_tmp = []
        df1 = []
        df_tmp = df_program.ix[(df_program.iD == rview['id']) & 
                                (rview['end_time'] >= df_program.START_TIME) &
                                (rview['start_time'] <= df_program.END_TIME)]
        df1 = rview.to_frame().transpose()
        tmp = pd.merge(df1, df_tmp,how='left')
        df_result.append(tmp)


    result = pd.concat(df_result, axis=0)
    del(df1, df_tmp, tmp)
    return result

请帮助我。我正在使用Visual Studio代码和Python 3.6

谢谢。

1 个答案:

答案 0 :(得分:1)

通常建议,如果可以避免,则从不遍历数据框。与任何mergejoin相比,循环都是超级慢。

有条件的联接在大熊猫中不是很好。但是,它们在SQL中非常简单。一个小型的生活黑客可能是pip install pandasql并实际使用SQL。另请参见here。下面的示例未经测试。

import pandasql as ps

sqlcode = '''
SELECT *
FROM df
JOIN df ON 1=1 
    AND df_program.iD = df.id 
    AND df.end_time >= df_program.START_TIME
    AND df.start_time <= df_program.END_TIME
'''

new_df = ps.sqldf(sqlcode, locals())

如果您不想使用pandassql,建议稍后合并并检查条件。当然,这需要更多的内存,具体取决于ID的重叠。再说一次,没有数据会有些棘手,但是有些类似

full_df = df.join(df, on='id', rsuffix='program_')
filtered_df = df.loc[(df.end_time >= df.program_START_TIME) & (df.start_time <= df.program_END_TIME)

如果它不适合内存,您可以尝试对dask数据帧执行相同的操作。

import dask.dataframe as dd

# Read your CSVs in like this
df = dd.read_csv('')
df_program = dd.read_csv('')

# Now make sure your ids are index in both dataframes

# Join and filter like above 
full_df = df.join(df, on='id', rsuffix='program_')
filtered_df = df.loc[(df.end_time >= df.program_START_TIME) & (df.start_time <= df.program_END_TIME)

# Write the result to a CSV or convert to pandas (if it fits your memory anyway):
df = full_df.compute()
相关问题