Python 在本例中,避免使用ItError的好方法是什么?
我讨论了ItErrors的性能问题,得到了良好的总体响应。这个问题是一个具体的案例,我希望您能帮助我更好地应用它,因为ItErrors的速度很慢 我相信这个问题对于任何一个新的python/pandas程序员来说都是有用的,因为他们觉得自己陷入了行迭代思维 我看到的使用“map”或“apply”的示例通常显示一个看起来足够直观的数据表。然而,我在两个表之间工作,它们很大(T1是250万行,T2是96000行) 下面是一个简单的示例(它在我的会话中起作用): 输出为:Python 在本例中,避免使用ItError的好方法是什么?,python,pandas,Python,Pandas,我讨论了ItErrors的性能问题,得到了良好的总体响应。这个问题是一个具体的案例,我希望您能帮助我更好地应用它,因为ItErrors的速度很慢 我相信这个问题对于任何一个新的python/pandas程序员来说都是有用的,因为他们觉得自己陷入了行迭代思维 我看到的使用“map”或“apply”的示例通常显示一个看起来足够直观的数据表。然而,我在两个表之间工作,它们很大(T1是250万行,T2是96000行) 下面是一个简单的示例(它在我的会话中起作用): 输出为: letter numbe
letter number2
0 a 0.5
1 b 0.1
[2 rows x 2 columns]
总体思路:
(显然,这种情况并不慢,因为它很小,但当处理数百万行时,它就慢了。请记住,在实际示例中,我在两个表中都有更多的列。)对我来说,看起来最简单的事情是在
字母
上进行合并,然后在上进行分组
import pandas as pd
import numpy as np
# Create the original tables
t1 = {'letter':['a','b'],
'number1':[50,-10]}
t2 = {'letter':['a','a','b','b'],
'number2':[0.2,0.5,0.1,0.4]}
table1 = pd.DataFrame(t1)
table2 = pd.DataFrame(t2)
table3 = table1.merge(table2,on='letter')
grouped = table3.groupby('letter')
def get_optimization(df):
product_column = df.number1 * df.number2
idx_of_prod_col_max = product_columns.idxmax()
return_val = df.ix[idx_of_prod_col_max]['number2']
return return_val
table3 = grouped.apply(get_optimization)
正如我在中发布的,有时问题不在于循环,而是不必要地将数据装箱到数据帧或序列中
def iterthrough():
ret = []
grouped = table2.groupby('letter', sort=False)
t2info = table2.to_records()
for index, letter, n1 in table1.to_records():
t2 = t2info[grouped.groups[letter].values]
maxrow = np.multiply(t2.number2, n1).argmax()
# `[1:]` removes the index column
ret.append(t2[maxrow].tolist()[1:])
return pd.DataFrame(ret, columns=('letter', 'number2'))
改善的方法包括:
使用groupby
和groups
索引避免重复的布尔计算
使用保存记录
以避免将记录从系列转换为系列
一开始合并T1和T2会得到50亿行,所以我想我需要避免这种情况(除非我低估了计算机的内存),我想你误解了合并——它需要合并列的交点。合并示例数据帧会得到一个包含四行(而不是8行)的数据帧(取决于传递给
how
参数的内容。内部
是默认值)。这对您有用吗?不幸的是没有。我得到这样一条信息:“ValueError:array太大了。”我非常肯定,在查看数据之后,我会得到50亿行(我同意这不是创建笛卡尔积)。我计划试用带有groupby功能的itertools。我可以创建两个分组对象,每个表一个。然后迭代查找“匹配”组。然后,我将像您所做的那样对每个表进行合并和应用,聚合到一个新表中。如果你知道如何做到这一点,我将非常感激在这个(微小的)例子中看到它。如果我成功了,我将自己发布:)
def iterthrough():
ret = []
grouped = table2.groupby('letter', sort=False)
t2info = table2.to_records()
for index, letter, n1 in table1.to_records():
t2 = t2info[grouped.groups[letter].values]
maxrow = np.multiply(t2.number2, n1).argmax()
# `[1:]` removes the index column
ret.append(t2[maxrow].tolist()[1:])
return pd.DataFrame(ret, columns=('letter', 'number2'))