我想将数据框中列的每个单元格传递给一个函数,然后该函数创建一个新单元格
我正在使用obscure package所以我将使用基础包来简化提出问题的方法,希望问题会很清楚。
方法:
加载数据
import pandas as pd
import math
df = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))
将一列的值传递给变量
lat = df['A']
通过将函数应用于变量来创建新列
df['sol'] = df.apply(math.sqrt(lat))
这给出了错误
TypeError: cannot convert the series to <type 'float'>
我使用 pyeto 包时遇到的错误实际上是
Traceback (most recent call last):
File "<ipython-input-10-b160408e9808>", line 1, in <module>
data['sol_dec'] = data['dayofyear'].apply(pyeto.sol_dec(data['dayofyear']), axis =1) # Solar declination
File "build\bdist.win-amd64\egg\pyeto\fao.py", line 580, in sol_dec
_check_doy(day_of_year)
File "build\bdist.win-amd64\egg\pyeto\_check.py", line 36, in check_doy
if not 1 <= doy <= 366:
File "C:\Users\AppData\Local\Continuum\Anaconda\lib\site-packages\pandas\core\generic.py", line 731, in __nonzero__
.format(self.__class__.__name__))
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().`
我认为这两种情况下的问题是相同的,该函数不会应用于数据帧列中的每个单元格,并产生错误。
我希望能够将函数应用于数据框列的每个单元格(即获取“A”列中每个单元格的平方根)。然后将此函数的结果存储为变量(或数据框中的另一列,即具有“sqrtA”列),然后将函数应用于该变量(或列)等等(即有一个新列“sqrtA” *100'。
我不知道如何做到这一点,非常感谢指导。
编辑
@EdChum 的回答 df['A'].apply(math.sqrt)
或data['dayofyear'].apply(pyeto.sol_dec)
(对于封装功能)帮助很大。
我现在遇到了包中另一个需要多个参数的函数的问题:
sha = pyeto.sunset_hour_angle(lat, sol_dec)
此函数不适用于数据框列,我有 lat
和sol_dec
存储为系列变量,但是当我尝试使用这些变量在数据框中创建新列时
data['sha'] = pyeto.sunset_hour_angle(lat, sol_dec)
我遇到了和以前一样的错误...
尝试将该函数应用于多列:
data['sha'] = data[['lat'],['sol_dec']].apply(pyeto.sunset_hour_angle)
给出错误:
Traceback (most recent call last):
File "<ipython-input-28-7b603745af93>", line 1, in <module>
data['sha'] = data[['lat'],['sol_dec']].apply(pyeto.sunset_hour_angle)
File "C:\Users\AppData\Local\Continuum\Anaconda\lib\site-packages\pandas\core\frame.py", line 1969, in __getitem__
return self._getitem_column(key)
File "C:\Users\AppData\Local\Continuum\Anaconda\lib\site-packages\pandas\core\frame.py", line 1976, in _getitem_column
return self._get_item_cache(key)
File "C:\Users\pflattery\AppData\Local\Continuum\Anaconda\lib\site-packages\pandas\core\generic.py", line 1089, in _get_item_cache
res = cache.get(item)
TypeError: unhashable type: 'list'
最佳答案
使用np.sqrt
,因为它可以理解数组:
In [86]:
df = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))
df['sol'] = np.sqrt(df['A'])
df
Out[86]:
A B C D sol
0 52 38 4 71 7.211103
1 59 4 36 15 7.681146
2 37 28 33 73 6.082763
3 58 26 4 96 7.615773
4 31 48 47 78 5.567764
5 43 58 45 4 6.557439
6 69 35 27 39 8.306624
.. .. .. .. .. ...
98 42 6 40 36 6.480741
99 22 44 11 24 4.690416
[100 rows x 5 columns]
要应用
您可以执行的功能:
In [87]:
import math
df['A'].apply(math.sqrt)
Out[87]:
0 7.211103
1 7.681146
2 6.082763
3 7.615773
4 5.567764
5 6.557439
6 8.306624
7 7.483315
8 7.071068
9 9.486833
...
95 3.464102
96 6.855655
97 5.385165
98 6.480741
99 4.690416
Name: A, dtype: float64
您尝试的是将 Series
传递给 math.sqrt
但 math.sqrt
不理解非标量值,因此错误。另外,当存在矢量化方法时,您应该避免使用 apply
,因为这对于 10K 行 df 来说会更快:
In [90]:
%timeit df['A'].apply(math.sqrt)
%timeit np.sqrt(df['A'])
100 loops, best of 3: 2.15 ms per loop
10000 loops, best of 3: 99.7 µs per loop
在这里您可以看到 numpy 版本的速度快了约 22 倍
关于您想要做的事情,以下内容应该有效:
data['dayofyear'].apply(pyeto.sol_dec)
编辑
将多列作为参数传递给方法:
data.apply(lambda x: pyeto.sunset_hour_angle(x['lat'],x['sol_dec']), axis=1)
关于python - 让函数在数据帧的每一行上工作(pandas),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36031749/