我有一个如下所示的数据框。
Name 2001 2002 2003 2004 2005 2006
Name1 2 5 0 0 4 6
Name2 1 4 2 0 4 0
Name3 0 5 0 0 0 2
我想使用熊猫计算每一行的累积平均值,但是在计算平均值时,必须忽略该值是否为零。
预期输出如下。
Name 2001 2002 2003 2004 2005 2006
Name1 2 3.5 3.5 3.5 3.75 4.875
Name2 1 2.5 2.25 2.25 3.125 3.125
Name3 0 5 5 5 5 3.5
答案 0 :(得分:3)
首先,在我看来,根据您的评论,您的计算中存在数学问题。 如果在第一行中使用3.5(即您当前的累计值)加4(第一行中2005的值)并给出->(3.5 + 4)/ 2 = 3.75,则存在错误稍后在第二列2005中。 实际上,您有(2.25 + 4)/ 2 = 3.125。您写的是3.175。
现在,我相信有更好的方法来实现我的解决方案,但在这里我能满足您的需求。
def cumulative_av(x):
b=[]
b.append(x[0])
for i in range(1,len(x)):
if(x[i]!=0 and b[-1]!=0):
b.append((x[i]+b[-1])*0.5)
elif(x[i]!=0 and b[-1]==0):
b.append(x[i])
elif(x[i]==0 and b[-1]!=0):
b.append(b[-1])
elif(x[i]==0 and b[-1]==0):
b.append(0)
return(b)
apd2=pd.DataFrame(columns=["2001", "2002", "2003", "2004", "2005", "2006"])
for i in range(3):
apd2.loc[i]=cumulative_av(apd.loc[i,].to_list())
其中“ apd”是您最初的熊猫数据框。 cumulative_av是一个生成您定义的功能的函数(我认为这是一个非常奇怪的函数)。
这是我的代码的结果:
2001 2002 2003 2004 2005 2006
0 2.0 3.5 3.50 3.50 3.750 4.875
1 1.0 2.5 2.25 2.25 3.125 3.125
2 0.0 5.0 5.00 5.00 5.000 3.500
答案 1 :(得分:0)
def cumavg(s):
avg=[s[0]]
for i in range(1,len(s)):
if s[i]!=0:
if avg[i-1] ==0:
avg.append(s[i])
else:
avg.append((s[i]+avg[i-1])/2)
else:
avg.append(avg[-1])
return np.array(avg)
df.apply(lambda s:cumavg(s),axis='columns')
答案 2 :(得分:0)
给出以下数据框:
import pandas as pd
data = {
'2001': {'Name1': 2, 'Name2': 1, 'Name3': 0},
'2002': {'Name1': 5, 'Name2': 4, 'Name3': 5},
'2003': {'Name1': 0, 'Name2': 2, 'Name3': 0},
'2004': {'Name1': 0, 'Name2': 0, 'Name3': 0},
'2005': {'Name1': 4, 'Name2': 4, 'Name3': 0},
'2006': {'Name1': 6, 'Name2': 0, 'Name3': 2}
}
df = pd.DataFrame(data)
基本上,您需要执行cumsum
(列方式,所以axis=1
),然后将其除以所有非cumsum
元素的0
。 / p>
这可以通过以下方式完成:
df.cumsum(axis=1) / (df != 0).cumsum(axis=1)
结果将是:
2001 2002 2003 2004 2005 2006
Name1 2.0 3.5 3.500000 3.500000 3.666667 4.25
Name2 1.0 2.5 2.333333 2.333333 2.750000 2.75
Name3 NaN 5.0 5.000000 5.000000 5.000000 3.50