我正在学习使用发电机,但不太了解它们是如何工作的。
我想要做的是迭代行并将每个单元格中的另一个单元格乘以一个单元格,然后创建一个包含结果的新列。
rate = (df['Fee'][i] for df['Fee'] in df / df['Costs'][i] for df['Costs'] in df * 100)
df['rate']=df.iterrows(rate)
所以,上面,我试图制作一台发电机,计算费用中的费用百分比。
我意识到使用for循环会更容易,但我想学习如何在这个实例中使用生成器。
下面的示例数据框。
Industry Expr1 Fee Costs
Food & Drink June 9970.320 116171.15
Music Industry June 7255.534 131492.59
Manufacturing June 5278.960 171315.01
Music Industry June 6120.596 143688.78
Telecommunications April 4123.986 78733.09
答案 0 :(得分:3)
简洁的答案是"你没有"。或者正如Pandas文档所说:
在进行数据分析时,与原始NumPy数组一样,通常不需要按值逐个循环。系列也可以传递给大多数期待ndarray的NumPy方法。
这也适用于DataFrame和许多其他利用ndarray
的结构。为了获得更多洞察力,我建议您更多地了解pandas / NumPy / SciPy如何在内部工作。
关于这个特定主题,我会指向Pandas - Intro to Data Structures - Data Alignment and Arithmetic和NumPy - Broadcasting
在幕后,这些软件包使用大量C代码来优化操作。虽然生成器/迭代器很棒,但它们永远无法匹配这样的优化代码。例如,假设您的问题示例是一个简单的测试。
np.all((df.Fee / df.Costs).values == np.array([x / y for x, y in df[['Fee', 'Costs']].values]))
True
%timeit (df.Fee / df.Costs).values
78.5 µs ± 1.88 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit np.array([x / y for x, y in df[['Fee', 'Costs']].values])
331 µs ± 12.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
正如您所看到的,Pandas内部使用的内置分割方法快了约5倍。这是一个非常小的样本量。
答案 1 :(得分:1)
你不需要发电机来做你想做的事;这可以通过以下方式轻松实现:
df['Rate'] = df.Fee / df.Costs
但是,为了完整性,这是发电机方式:
rate = [x / y for x, y in df[['Fee', 'Costs']].values]
df[['Fee', 'Costs']]
提取相关列,.values
将该数据框转换为num_rows x 2
numpy
数组,并为其编写迭代器。
当您想要对数据执行更复杂的操作时,可能必须使用生成器语法,例如将其传递给任意函数f(fee, cost)
。