根据我的理解,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
我有一个像这样的数据框:
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) 我有一个 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.groupby.aggregate我正在尝试使用自定义聚合函数来提高操作的性能。我注意到 - 如果我错了,请纠正我 -pandas按顺序调用每个块上的聚合函数(我怀疑它是一个简单的for循环)。
由于pandas很大程度上基于,有没有办法使用 的矢量化特征numpy来加速计算?numpy
在我的代码中,我需要将风数据平均样本聚合在一起。虽然平均风速很简单,但平均风向需要更多的临时代码(例如,1 度和 359 度的平均值是 0 度,而不是 180 度)。
我的聚合函数的作用是:
其功能是:
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) 何时以及为何忽略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) 如果值不为空,如何将自定义函数应用于每列的每个元素?
假设我有一个 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)
如何摆脱这个错误?
我喜欢使用 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) 目标:在多个预测列和一个实际数据列上使用自定义 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) 当我打电话时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新手在这里。我试图了解 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) 我一直在听到很多关于 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不使用应用的情况下计算列。
我正在寻找一种方法来链接 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)