当前位置: 首页 > 面试题库 >

将函数应用于熊猫数据框的每一行以创建两个新列

濮阳宜
2023-03-14
问题内容

我有一个熊猫DataFrame,st其中包含多个列:

<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 53732 entries, 1993-01-07 12:23:58 to 2012-12-02 20:06:23
Data columns:
Date(dd-mm-yy)_Time(hh-mm-ss)       53732  non-null values
Julian_Day                          53732  non-null values
AOT_1020                            53716  non-null values
AOT_870                             53732  non-null values
AOT_675                             53188  non-null values
AOT_500                             51687  non-null values
AOT_440                             53727  non-null values
AOT_380                             51864  non-null values
AOT_340                             52852  non-null values
Water(cm)                           51687  non-null values
%TripletVar_1020                    53710  non-null values
%TripletVar_870                     53726  non-null values
%TripletVar_675                     53182  non-null values
%TripletVar_500                     51683  non-null values
%TripletVar_440                     53721  non-null values
%TripletVar_380                     51860  non-null values
%TripletVar_340                     52846  non-null values
440-870Angstrom                     53732  non-null values
380-500Angstrom                     52253  non-null values
440-675Angstrom                     53732  non-null values
500-870Angstrom                     53732  non-null values
340-440Angstrom                     53277  non-null values
Last_Processing_Date(dd/mm/yyyy)    53732  non-null values
Solar_Zenith_Angle                  53732  non-null values
dtypes: datetime64[ns](1), float64(22), object(1)

我想基于对数据框的每一行应用一个函数为此数据框创建两个新列。我不想多次调用该函数(例如,通过执行两次单独的apply调用),因为它占用大量计算资源。我尝试通过两种方式来执行此操作,但它们都不起作用:

使用apply

我编写了一个函数,该函数接受aSeries并返回我想要的值的元组:

def calculate(s):
    a = s['path'] + 2*s['row'] # Simple calc for example
    b = s['path'] * 0.153
    return (a, b)

尝试将此应用于DataFrame会出现错误:

st.apply(calculate, axis=1)
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-248-acb7a44054a7> in <module>()
----> 1 st.apply(calculate, axis=1)

C:\Python27\lib\site-packages\pandas\core\frame.pyc in apply(self, func, axis, broadcast, raw, args, **kwds)
   4191                     return self._apply_raw(f, axis)
   4192                 else:
-> 4193                     return self._apply_standard(f, axis)
   4194             else:
   4195                 return self._apply_broadcast(f, axis)

C:\Python27\lib\site-packages\pandas\core\frame.pyc in _apply_standard(self, func, axis, ignore_failures)
   4274                 index = None
   4275 
-> 4276             result = self._constructor(data=results, index=index)
   4277             result.rename(columns=dict(zip(range(len(res_index)), res_index)),
   4278                           inplace=True)

C:\Python27\lib\site-packages\pandas\core\frame.pyc in __init__(self, data, index, columns, dtype, copy)
    390             mgr = self._init_mgr(data, index, columns, dtype=dtype, copy=copy)
    391         elif isinstance(data, dict):
--> 392             mgr = self._init_dict(data, index, columns, dtype=dtype)
    393         elif isinstance(data, ma.MaskedArray):
    394             mask = ma.getmaskarray(data)

C:\Python27\lib\site-packages\pandas\core\frame.pyc in _init_dict(self, data, index, columns, dtype)
    521 
    522         return _arrays_to_mgr(arrays, data_names, index, columns,
--> 523                               dtype=dtype)
    524 
    525     def _init_ndarray(self, values, index, columns, dtype=None,

C:\Python27\lib\site-packages\pandas\core\frame.pyc in _arrays_to_mgr(arrays, arr_names, index, columns, dtype)
   5411 
   5412     # consolidate for now
-> 5413     mgr = BlockManager(blocks, axes)
   5414     return mgr.consolidate()
   5415

C:\Python27\lib\site-packages\pandas\core\internals.pyc in __init__(self, blocks, axes, do_integrity_check)
    802 
    803         if do_integrity_check:
--> 804             self._verify_integrity()
    805 
    806         self._consolidate_check()

C:\Python27\lib\site-packages\pandas\core\internals.pyc in _verify_integrity(self)
    892                                      "items")
    893             if block.values.shape[1:] != mgr_shape[1:]:
--> 894                 raise AssertionError('Block shape incompatible with manager')
    895         tot_items = sum(len(x.items) for x in self.blocks)
    896         if len(self.items) != tot_items:

AssertionError: Block shape incompatible with manager

然后,我将apply使用此问题中显示的方法将从返回的值分配给两个新列。但是,我什至无法做到这一点!如果我只返回一个值,则一切正常。

使用循环:

我首先创建了数据框的两个新列,并将它们设置为None

st['a'] = None
st['b'] = None

然后遍历所有索引,并尝试修改None我在那里输入的这些值,但是我所做的修改似乎没有用。也就是说,没有错误发生,但是DataFrame似乎没有被修改。

for i in st.index:
    # do calc here
    st.ix[i]['a'] = a
    st.ix[i]['b'] = b

我认为这两种方法都行得通,但都没有。那么,我在这里做错了什么?最好的,最“ pythonic”和“ pandaonic”方法是什么?


问题答案:

为了使第一种方法可行,请尝试返回一个Series而不是一个元组(apply引发异常,因为它不知道如何将行粘合在一起,因为列数与原始框架不匹配)。

def calculate(s):
    a = s['path'] + 2*s['row'] # Simple calc for example
    b = s['path'] * 0.153
    return pd.Series(dict(col1=a, col2=b))

如果替换,则第二种方法应该可行:

st.ix[i]['a'] = a

与:

st.ix[i, 'a'] = a


 类似资料:
  • 我想通过对两个现有列应用函数,在数据框中创建一个新列。根据这个答案,当我只需要一列作为参数时,我就能够创建一个新列: 但是,当函数需要多个参数时,我不知道如何执行相同的操作。例如,如何通过将列a和列B传递给下面的函数来创建新列?

  • 问题内容: 我有以下数据框: 现在,我想创建另一个列,其值在和之间最大。因此,我希望将其作为输出: 我试过了 : 但是,这会引发语法错误。我没有任何方法可以在熊猫中做到这一点。我的实际数据框太复杂了,因此我想为此提供一个通用的解决方案。有任何想法吗? 问题答案: 您可以使用: 解决方案: 或更简单的发现:

  • 问题内容: 我有两个,都被索引。我需要将元素添加在一起以形成一个new ,但前提是索引和列相同。如果该项不存在于之一,则应将其视为零。 我试过使用,但这无论索引和列如何。还尝试了一个简单的方法,但是如果两个数据框都没有该元素,则给出a 。 有什么建议? 问题答案: 怎么样

  • 问题内容: 我有从构成的DataFrame 。一行包含96个值,我想将DataFrame与值72分开。 以便将行的前72个值存储在Dataframe1中,并将行的后24个值存储在Dataframe2中。 我按如下方式创建我的DF: 问题是:如何拆分它们?:) 问题答案: (iloc文档)

  • 我创建了一个名为的函数,该函数采用了如图所示的这3个参数,结果是新参数。我想将此函数应用于一个数据帧,其中函数参数是数据帧中的某些列,并希望将函数的输出参数添加为数据帧中的新参数,在数据帧中为每行计算函数。

  • 在中,可以对数据帧中的每一列应用一些groupby函数,例如: 假设我想应用一个lambda函数