标签: pandas-apply

pandas df.apply意外地改变了数据帧

根据我的理解,pandas.DataFrame.apply不会在内部应用更改,我们应该使用其返回对象来保留任何更改.但是,我发现了以下不一致的行为:

让我们应用一个虚函数,以确保原始df保持不变:

>>> def foo(row: pd.Series):
...     row['b'] = '42'

>>> df = pd.DataFrame([('a0','b0'),('a1','b1')], columns=['a', 'b'])
>>> df.apply(foo, axis=1)
>>> df
    a   b
0   a0  b0
1   a1  b1
Run Code Online (Sandbox Code Playgroud)

这表现得如预期.但是,如果我们修改初始化此df的方式,foo将在适用的位置应用更改:

>>> df2 = pd.DataFrame(columns=['a', 'b'])
>>> df2['a'] = ['a0','a1']
>>> df2['b'] = ['b0','b1']
>>> df2.apply(foo, axis=1)
>>> df2
    a   b
0   a0  42
1   a1  42
Run Code Online (Sandbox Code Playgroud)

我还注意到,如果列dtypes不是'object'类型,则上述情况不正确.为什么apply()在这两个上下文中表现不同?

Python:3.6.5

熊猫:0.23.1

python dataframe pandas pandas-apply

9
推荐指数
1
解决办法
1099
查看次数

应用函数创建以多列作为参数的字符串

我有一个像这样的数据框:

     name .  size . type    .  av_size_type
0    John .   23  . Qapra'  .            22
1     Dan .   21  . nuk'neH .            12
2  Monica .   12  . kahless .            15
Run Code Online (Sandbox Code Playgroud)

我想用一个句子创建一个新列,如下所示:

    name .  size . type    .  av_size_type  .   sentence
0    John .   23 . Qapra'  .            22  .   "John has size 23, above the average of Qapra' type (22)"
1     Dan .   21 . nuk'neH .            12  .   "Dan has size 21, above the average of nuk'neH …
Run Code Online (Sandbox Code Playgroud)

python dataframe pandas pandas-apply

7
推荐指数
2
解决办法
1570
查看次数

使用数据框格式化另一个数据框的样式

我有一个 pandas 数据框,我想根据另一个相同形状/大小的数据框的值来设置格式的样式。我正在尝试使用 applymap。

这是一个例子:

t1= pd.DataFrame({'x':['A','B','C'], 'y':['C','B','D']})
t2= pd.DataFrame({'x':[0.3,0.2,0.7], 'y':[1,0.3,2]})

def color_cells(s, threshold=0.5):
    if s > threshold:
        return 'color:{0}; font-weight:bold'.format('red')
    else:
        return ''

#Tried
t1.style.applymap(t2.applymap(color_cells))

Run Code Online (Sandbox Code Playgroud)

理想情况下,在 t1 中,t2 中的相应单元格>0.5,则 t1 中的值采用“红色粗体”。

但是,我不确定应该使用什么模式来获得所需的效果。

pandas pandas-apply pandas-styles

5
推荐指数
1
解决办法
2783
查看次数

提高性能(矢量化?) pandas.groupby.aggregate

pandas.groupby.aggregate我正在尝试使用自定义聚合函数来提高操作的性能。我注意到 - 如果我错了,请纠正我 -pandas按顺序调用每个块上的聚合函数(我怀疑它是一个简单的for循环)。

由于pandas很大程度上基于,有没有办法使用 的矢量化特征numpy来加速计算?numpy

我的代码

在我的代码中,我需要将风数据平均样本聚合在一起。虽然平均风速很简单,但平均风向需要更多的临时代码(例如,1 度和 359 度的平均值是 0 度,而不是 180 度)。

我的聚合函数的作用是:

  1. 删除 NaN
  2. 如果不存在其他值则返回 NaN
  3. 检查是否存在指示可变风向的特殊标志。如果是,则返回标志
  4. 使用矢量平均算法平均风向

其功能是:

def meandir(x):
    '''
    Parameters
    ----------
    x : pandas.Series
        pandas series to be averaged

    Returns
    -------
    float
        averaged wind direction
    '''

    # Removes the NaN from the recording
    x = x.dropna()

    # If the record is empty, return NaN
    if len(x)==0:
        return np.nan

    # If the record …
Run Code Online (Sandbox Code Playgroud)

python pandas pandas-apply pandas-groupby

5
推荐指数
1
解决办法
688
查看次数

为什么 pandas.GroupBy.apply() 在某些情况下会忽略排序标志?

何时以及为何忽略DataFrame分组的排序标志pd.GroupBy.apply()?通过一个例子可以最好地理解这个问题。在以下虚拟问题的 4 个等效解决方案中,方法 1 和 4 观察排序标志,而方法 2 和 3 由于某种原因忽略它。

import pandas as pd
import numpy as np 

#################################################
# Construct input data:
cats = list("bcabca")
vals = np.arange(0,10*len(cats),10) 
df = pd.DataFrame({"i": cats, "ii": vals})

# df:
#      i  ii
#   0  b   0
#   1  c  10
#   2  a  20
#   3  b  30
#   4  c  40
#   5  a  50

# Groupby with sort=True
g = df.groupby("i", sort=True)

#################################################
# 1) …
Run Code Online (Sandbox Code Playgroud)

python dataframe pandas pandas-apply pandas-groupby

5
推荐指数
1
解决办法
141
查看次数

Pandas 应用并映射到每列的每个元素

如果值不为空,如何将自定义函数应用于每列的每个元素?

假设我有一个 10 列的数据框,如果 pd.notnull(x),我想将 lower() 函数应用于仅 4 列的每个元素,否则只保留 None 作为值。

我尝试这样使用,

s.apply(lambda x: change_to_lowercase(x), axis = 1)

def change_to_lowercase(s):

    s['A'] =  s['A'].map(lambda x: x.lower() if pd.notnull(x) else x)
    s['B'] = s['B'].map(lambda x: x.lower() if pd.notnull(x) else x)
    s['C'] = s['C'].map(lambda x: x.lower() if pd.notnull(x) else x)
    s['D'] = s['D'].map(lambda x: x.lower() if pd.notnull(x) else x)
    return s
Run Code Online (Sandbox Code Playgroud)

但由于我的列是混合数据类型(NaN 作为 float,其余为 unicode)。这给我带来了一个错误 -

float has no attribute map.
Run Code Online (Sandbox Code Playgroud)

如何摆脱这个错误?

python python-2.7 pandas pandas-apply

4
推荐指数
1
解决办法
5429
查看次数

pandas groupby 应用于多列以生成新列

我喜欢使用 groupby-apply 在 Pandas 数据框中生成一个新列。

例如,我有一个数据框:

df = pd.DataFrame({'A':[1,2,3,4],'B':['A','B','A','B'],'C':[0,0,1,1]})
Run Code Online (Sandbox Code Playgroud)

并尝试通过 groupby-apply 生成一个新列“D”。

这有效:

df = df.assign(D=df.groupby('B').C.apply(lambda x: x - x.mean()))
Run Code Online (Sandbox Code Playgroud)

因为(我认为)它返回一个与数据帧具有相同索引的系列:

In [4]: df.groupby('B').C.apply(lambda x: x - x.mean())
Out[4]:
0   -0.5
1   -0.5
2    0.5
3    0.5
Name: C, dtype: float64
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试使用多列生成新列,则无法将其直接分配给新列。所以这不起作用:

 df.assign(D=df.groupby('B').apply(lambda x: x.A - x.C.mean()))
Run Code Online (Sandbox Code Playgroud)

回来

TypeError: incompatible index of inserted column with frame index
Run Code Online (Sandbox Code Playgroud)

事实上, groupby-apply 返回:

In [8]: df.groupby('B').apply(lambda x: x.A - x.C.mean())
Out[8]:
B
A  0    0.5
   2    2.5
B  1    1.5
   3    3.5
Name: …
Run Code Online (Sandbox Code Playgroud)

python pandas pandas-apply pandas-groupby

4
推荐指数
2
解决办法
5526
查看次数

Pandas:自定义 WMAPE 函数聚合函数到多列而无需 for 循环?

目标:在多个预测列和一个实际数据列上使用自定义 WMAPE(加权平均绝对百分比误差)函数对 Pandas 数据框进行分组,无需 for 循环。我知道输出数据帧的 for 循环和合并可以解决问题。我想有效地做到这一点。

有: WMAPE函数,成功使用WMAPE函数在dataframe的一个预测列上。一列实际数据,可变数量的预测列。

输入数据: Pandas DataFrame 具有多个分类列(City、Person、DT、HOUR)、一个实际数据列(Actual)和四个预测列(Forecast_1 ... Forecast_4)。请参阅 csv 链接:https ://www.dropbox.com/s/tidf9lj80a1dtd8/data_small_2.csv ? dl =1

需要: WMAPE 函数在 groupby 期间在多个列上应用,并将预测列列表输入 groupby 行。

所需输出:具有分类组列和 WMAPE 的所有列的输出数据框。标签是首选但不是必需的(下面的输出图像)。

到目前为止成功的代码: 两个 WMAPE 函数:一个接收两个系列并输出单个浮点值 (wmape),一个用于 groupby (wmape_gr) 的结构化:

def wmape(actual, forecast):
    # we take two series and calculate an output a wmape from it

    # make a series called mape
    se_mape = abs(actual-forecast)/actual

    # get a float of the sum of the actual
    ft_actual_sum = …
Run Code Online (Sandbox Code Playgroud)

python forecasting pandas pandas-apply pandas-groupby

4
推荐指数
2
解决办法
3170
查看次数

pandas groupby apply 真的很慢

当我打电话时df.groupby([...]).apply(lambda x: ...),表现很糟糕。有没有更快/更直接的方法来做这个简单的查询?

为了证明我的观点,这里有一些代码来设置 DataFrame:

import pandas as pd

df = pd.DataFrame(data=
    {'ticker': ['AAPL','AAPL','AAPL','IBM','IBM','IBM'],
       'side': ['B','B','S','S','S','B'],
       'size': [100, 200, 300, 400, 100, 200],
      'price': [10.12, 10.13, 10.14, 20.3, 20.2, 20.1]})


    price   side     size   ticker
0   10.12   B        100    AAPL
1   10.13   B        200    AAPL
2   10.14   S        300    AAPL
3   20.30   S        400    IBM
4   20.20   S        100    IBM
5   20.10   B        200    IBM
Run Code Online (Sandbox Code Playgroud)

现在这是我需要加速的非常慢的部分:

%timeit avgpx = df.groupby(['ticker','side']) \
.apply(lambda group: (group['size'] * group['price']).sum() / group['size'].sum())

3.23 …
Run Code Online (Sandbox Code Playgroud)

python lambda pandas pandas-apply pandas-groupby

3
推荐指数
1
解决办法
2929
查看次数

python pandas groupby/apply:传递给apply函数的到底是什么?

Python新手在这里。我试图了解 pandas groupby 和 apply 方法是如何工作的。我找到了这个简单的例子,我粘贴在下面:

import pandas as pd

ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',
   'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
   'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
   'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
   'Points':[876,789,863,673,741,812,756,788,694,701,804,690]}

df = pd.DataFrame(ipl_data)
Run Code Online (Sandbox Code Playgroud)

数据框df如下所示:

      Team  Rank  Year  Points
0   Riders     1  2014     876
1   Riders     2  2015     789
2   Devils     2  2014     863
3   Devils     3  2015     673
4    Kings     3  2014     741
5    kings     4  2015     812 …
Run Code Online (Sandbox Code Playgroud)

python dataframe pandas pandas-apply pandas-groupby

3
推荐指数
1
解决办法
1614
查看次数

Python pandas:我们可以避免在 groupby/apply 的情况下申请吗?

我一直在听到很多关于 pandas apply 很慢的消息,应该尽可能少地使用它。

我这里有一个情况:

df = pd.DataFrame({'Date': ['2019-01-02', '2019-01-03', '2019-01-04'],
          'Fund_ID': [9072, 9072, 9072],
          'Fund_Series': ['A', 'A', 'A'],
          'Value': [1020.0, 1040.4, 1009.188],
          'Dividend': [0.0, 0.0, 52.02]})
Run Code Online (Sandbox Code Playgroud)

我想在分组后做一些调整后的加权操作,如下所示:

df['Pct_Change_Adjusted'] = df.groupby(['Fund_ID', 'Fund_Series'], as_index=False) \
                              .apply(lambda x: (x.Value + x.Dividend)/(x.Value.shift()+x.Dividend.shift())  ) \
                              .reset_index(drop=True).values[0]

print(df)

         Date  Dividend  Fund_ID Fund_Series     Value  Pct_Change_Adjusted
0  2019-01-02      0.00     9072           A  1020.000                  NaN
1  2019-01-03      0.00     9072           A  1040.400                 0.02
2  2019-01-04     52.02     9072           A  1009.188                 0.02
Run Code Online (Sandbox Code Playgroud)

有没有替代方案 apply可以提高效率或至少是第二种做事方式!!

注意:我不是在谈论 dask 和其他并行化,只谈论纯熊猫。

必需:
Pct_Change_Adjusted不使用应用的情况下计算列。

python pandas pandas-apply pandas-groupby

2
推荐指数
1
解决办法
262
查看次数

链接 groupby 并应用 pandas

我正在寻找一种方法来链接 groupby 并应用,就像这样(参见下面的代码以获得具体示例):

df.groupby("a").apply(func_1).groupby("b").apply(func_2)
Run Code Online (Sandbox Code Playgroud)

我想它不起作用,因为 groupby 需要输入一个数据帧,这并不总是上面第二个 groupby 的情况(可以输入一个系列,参见示例)。一个解决方案可能是让第一个应用程序输出 func_1 的结果加上原始数据帧,但我还没有找到如何做到这一点。

我正在寻找一种通用的解决方法,而不仅仅是这个特定示例的解决方法。

示例:假设我想计算 b 中每个组的 a 路缘下面积,然后计算 c 中每个组的这些区域的总和。

df=pd.DataFrame({"a":np.arange(8),"b":np.repeat(np.arange(4),2),
"c":np.repeat(np.arange(2),4)})

df
   a  b  c
0  0  0  0
1  1  0  0
2  2  1  0
3  3  1  0
4  4  2  1
5  5  2  1
6  6  3  1
7  7  3  1


df.groupby("b").apply(lambda x: trapz(x["a"])).groupby("c").apply(sum)   
Traceback (most recent call last):
[...]
KeyError: 'c'


#Expected output
c
0     3.0
1    11.0


#I know that this code …
Run Code Online (Sandbox Code Playgroud)

python pandas pandas-apply pandas-groupby

1
推荐指数
1
解决办法
3002
查看次数