使用Pandas迭代向数据框添加列

5

我有一些相对简单的代码,但是我仍然在努力组合它们。我已经将一个CSV读入到数据框中。这个CSV是面板数据(即每行都有唯一的公司和年份观察值)。我有两列想要执行函数,然后根据函数的输出创建新变量。

以下是我的代码:

#Loop through rows in a CSV file
for index, rows in df.iterrows():
    #Start at column 6 and go to the end of the file
    for row in rows[6:]:
        data = perform_function1( row )
        output =  perform_function2(data)    
        df.ix[index, 'new_variable'] = output
        print output

我希望这段代码从第6列开始迭代,然后到文件的结尾(例如,我有两列要对其执行函数Column6和Column7),然后根据执行的函数创建新列(例如,Output6和Output7)。上面的代码返回Column7的输出,但我无法创建一个变量,使我能够捕获来自两列的输出(即,一个新变量,不被循环覆盖)。我在Stackoverflow上搜索,没有看到与我的问题直接相关的内容(也许是因为我太菜了?)。我真的很感激您的帮助。
谢谢,
TT
P.S.我不确定是否提供了足够的细节。如果需要提供更多信息,请告诉我。

你能举个例子说明你的输入和期望输出吗?当你说“一个新变量”时,你实际上是指“一个新列名”吗? - BrenBarn
是的——一个新的列名。我的输入是一段文本。该函数基于输入文本计算可读性统计数据。因此,新变量(或新列)基本上将是基于文本的可读性统计数据(Flesch-Kincaid分数)。 - TaterTots
for row in rows[6:] 这段代码有些令人困惑,因为 rows 是数据集中的一行,而 for row in rows[6:] 实际上是在迭代该行的列。 - GeauxEric
3个回答

4

迭代操作并不能充分利用Pandas的能力。Pandas的优势在于高效地对整个数据框应用操作,而不是逐行迭代。这对于像这样需要在数据上链式调用多个函数的任务非常有效。您应该能够在一行代码中完成整个任务。

df["new_variable"] = df.ix[6:].apply(perform_function1).apply(perform_function2)

perform_function1将被应用于每一行数据,perform_function2将被应用于第一个函数的结果。


谢谢!我尝试了这种方法,但是收到了以下错误信息:TypeError: ('expected string or buffer', u'occurred at index CaseNum')我认为这是因为我的函数是针对单个字符串(沿列迭代)编写的,而不是应用于整行。 - TaterTots
等等,这两个函数都是针对单个字符串而不是整行进行操作的,还是只有perform_function1?如果你的函数不太复杂,也许包含它们会更有帮助。 - ASGM
这些函数有点复杂。它们旨在应用于单个字符串。 - TaterTots
@TaterTots 它们返回什么?perform_function1 返回单个值还是多个值?perform_function2 呢? - ASGM
这两个函数都返回单个值。解决这个问题的答案非常简单。我只需要通过添加计数器来创建一个动态变量名,并在第二个for循环中添加以下代码:name = df.columns[i+6] df.ix[index, 'new_var' + '_' + str(name)] = perform_function2感谢您的帮助! - TaterTots

1
如果您想对数据框中的特定列应用函数
# Get the Series
colmun6 = df.ix[:, 5]  
# perform_function1 applied to each row
output6 = column6.apply(perform_function1)  
df["new_variable"] = output6

0

Pandas在逐行操作时速度相当慢:最好使用整个数据框的append, concat, mergejoin功能。

为了说明原因,让我们考虑一个随机的DataFrame示例:

import numpy as np
import pandas as pd
dates = pd.date_range('20130101', periods=6)
df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD'))
df2 = df.copy()
# operation to concatenate two dataframes
%timeit pd.concat([df2, df])
1000 loops, best of 3: 737 µs per loop
 %timeit df.loc['2013-01-01']
1000 loops, best of 3: 251 µs per loop
# single element operation
%timeit df.loc['2013-01-01', 'A'] = 3
1000 loops, best of 3: 218 µs per loop

注意Pandas如何高效地处理整个数据框操作,以及如何低效地处理单个元素的操作?

如果我们扩展这一点,相同的趋势会发生,只是更加明显:

df = pd.DataFrame(np.random.randn(200, 300))
# single element operation
%timeit df.loc[1,1] = 3
10000 loops, best of 3: 74.6 µs per loop
df2 = df.copy()
# full dataframe operation
%timeit pd.concat([df2, df])
1000 loops, best of 3: 830 µs per loop

Pandas对整个200x300的DataFrame执行操作的速度比对单个元素执行操作快了大约6,000倍。简而言之,迭代会破坏使用Pandas的整个目的。如果您需要逐个访问数据框中的元素,请考虑使用字典代替。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接