您好,我最近发布了一个有关执行合并以获取熊猫数据框并返回满足条件的列的问题。
完整的详细信息可以在这里找到:
(不确定我是否应该发布整个问题以使该帖子保持独立,所以我现在只留下一个链接)。
给出的解决方案效果很好,并且当我需要较小的数据集时,请考虑少于一千行。
这是建议的答案:
m=(df1.assign(key=1).merge(df2.assign(key=1),on='key',suffixes=('','_y')).drop('key', 1)
.query("(Code==Code_y)&(Price<=Price_y)"))
m.groupby(['Code','Price'],sort=False)['Price_y'].first().reset_index(name='New Price'
但是,当我开始在较大的数据集上使用它时(这是我的要求),它开始减慢到几乎无法使用的水平,以为5分钟+数千行的行数,并由于内存错误而彻底崩溃。尝试进一步增加数据框中的行。
我忍不住想,必须有一种更好的方法来更有效地执行此操作。
有人有什么建议吗?
答案 0 :(得分:0)
请尝试:
m=df1.set_index('Code').join(df2.set_index('Code'),rsuffix='_New')
df1.join(m[m.Price<=m.Price_New].groupby('Price',sort=False)['Price_New']
.first().reset_index(drop=True))
Code Price Price_New
0 X 4.30 4.5
1 X 2.50 2.5
2 X 4.00 4.0
3 X 1.50 1.5
4 X 0.24 0.5
5 X 1.00 1.0
6 X 1.30 1.5
7 Y 3.90 4.0
8 Y 2.60 3.0
样本df的性能:
答案 1 :(得分:0)
请考虑以下替代解决方案。在这里,我们遍历不同的Code
值,并为每个New Price
搜索适当的Price
。与原始方式相比,在时间和记忆上应该更加有效。效率也可以通过优化和/或numba
来增强。
import numpy as np
import pandas as pd
def get_all_new(pd_series, result):
result[pd_series.name] = np.sort(pd_series.unique())
def find_new_group(pd_series, sorted_arrays):
return pd_series.apply(lambda x: find_new(x, sorted_arrays[pd_series.name]))
def find_new(value, sorted_array):
pos = np.searchsorted(sorted_array, value)
return sorted_array[pos] if pos < sorted_array.size else None # None OR value ???
if __name__ == '__main__':
N1, N2, M1, M2 = 5, 5, 5, 5
df1 = pd.DataFrame(
{'Code': ['X'] * N1 + ['Y'] * N2,
'Price': np.random.randint(1, 100, N1 + N2) / 10})
df2 = pd.DataFrame(
{'Code': ['X'] * M1 + ['Y'] * M2,
'Price': np.random.randint(1, 100, M1 + M2) / 10})
print(df1)
print(df2)
all_new = dict()
# collect all new prices for every Code
df2.groupby('Code')['Price'].apply(lambda x: get_all_new(x, all_new))
# find appropriate new price for every old price
df1['New Price'] = df1.groupby('Code')['Price'].apply(lambda x: find_new_group(x, all_new))
print(df1)
输出:
Code Price
0 X 7.8
1 X 6.6
2 X 3.2
3 X 0.3
4 X 4.7
5 Y 0.5
6 Y 1.1
7 Y 8.9
8 Y 6.7
9 Y 0.5
Code Price
0 X 6.9
1 X 4.6
2 X 2.3
3 X 7.6
4 X 2.4
5 Y 0.8
6 Y 3.4
7 Y 0.4
8 Y 4.2
9 Y 9.6
Code Price New Price
0 X 7.8 NaN
1 X 6.6 6.9
2 X 3.2 4.6
3 X 0.3 2.3
4 X 4.7 6.9
5 Y 0.5 0.8
6 Y 1.1 3.4
7 Y 8.9 9.6
8 Y 6.7 9.6
9 Y 0.5 0.8
使用N1, N2, M1, M2 = ...
100_000
-518 ms ± 2.25 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
,
1_000_000
-5.29 s ± 72.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
。