我在DataFrame中有三列。我想取Streak_Count列中的数字,并总结MON TOTAL中返回的单元格数。结果显示在WANTED RESULT中,如下所示。我无法弄清楚的问题是将单元格的数量相加,可以是任何数字>>在这个例子中介于1和4之间。
scss
@import '~bootstrap/scss/bootstrap.scss';
答案 0 :(得分:1)
这一切都是为了找到合适的东西来分组。在这种情况下,STREAK_COUNT
的反向累积和将为您提供所需的内容。
首先我们创建数据框:
import pandas as pd
>>> df = pd.DataFrame({'MON TOTAL':[1.123077, -1.296178, -6.355612, 5.634692, 4.180605, -0.101016, -0.706125,
0.368579, 3.822277, 2.233359, 15.219644, -2.647693, 1.599094],
'STREAK_COUNT':[1, 0, 2, 0, 2, 0, 2, 0, 0, 0, 4, 1, 1]},
index=['1/2/1992', '2/3/1992', '3/2/1992', '4/1/1992', '5/1/1992', '7/1/1992', '8/3/1992',
'10/1/1992', '11/2/1992', '1/4/1993', '2/1/1993', '3/1/1993', '4/1/1993'])
>>> df
MON TOTAL STREAK_COUNT
1/2/1992 1.123077 1
2/3/1992 -1.296178 0
3/2/1992 -6.355612 2
4/1/1992 5.634692 0
5/1/1992 4.180605 2
7/1/1992 -0.101016 0
8/3/1992 -0.706125 2
10/1/1992 0.368579 0
11/2/1992 3.822277 0
1/4/1993 2.233359 0
2/1/1993 15.219644 4
3/1/1993 -2.647693 1
4/1/1993 1.599094 1
接下来找到组,计算每个组的总和,并将结果连接到原始数据帧:
>>> groups = df['STREAK_COUNT'][::-1].cumsum()[::-1]
>>> df['RESULT'] = df.groupby(groups)['MON TOTAL'].transform('sum')
>>> df
MON TOTAL STREAK_COUNT RESULT
1/2/1992 1.123077 1 1.123077
2/3/1992 -1.296178 0 -7.651790
3/2/1992 -6.355612 2 -7.651790
4/1/1992 5.634692 0 9.815297
5/1/1992 4.180605 2 9.815297
7/1/1992 -0.101016 0 -0.807141
8/3/1992 -0.706125 2 -0.807141
10/1/1992 0.368579 0 21.643859
11/2/1992 3.822277 0 21.643859
1/4/1993 2.233359 0 21.643859
2/1/1993 15.219644 4 21.643859
3/1/1993 -2.647693 1 -2.647693
4/1/1993 1.599094 1 1.599094
如果您只想在每条条纹结束时得到结果,请使用遮罩过滤它:
>>> df[df['STREAK_COUNT'] > 0]
MON TOTAL STREAK_COUNT RESULT
1/2/1992 1.123077 1 1.123077
3/2/1992 -6.355612 2 -7.651790
5/1/1992 4.180605 2 9.815297
8/3/1992 -0.706125 2 -0.807141
2/1/1993 15.219644 4 21.643859
3/1/1993 -2.647693 1 -2.647693
4/1/1993 1.599094 1 1.599094
答案 1 :(得分:0)
编辑1:
对整个列执行操作而不是迭代并使用对象/迭代器从而避免列表的高效版本。
这里的变化是,
1)我们首先获得" STREAK_COUNT"转换为tuple
,索引为第一个值," STREAK_COUNT"作为第二个使用enumerate
。由于enumerate
是可迭代的,我们可以在步骤(3)中直接使用它而不是转换为列表。
2)定义getTotal()
函数并独立处理(1)中的每个值以生成相应的"结果"值。
3)将getTotal()
映射到整个" STREAK_COUNT"枚举在步骤(1)中生成的对象以获得所需的"结果"列。
工作代码
def getTotal(x):
pos = [i for i in range(x[0],x[0]-x[1],-1)]
total = sum(df.iloc[pos, 0])
func = lambda x : x if x !=0 else ''
return func(total)
df[ "RESULT" ] = map(lambda x: getTotal(x), enumerate(df["STREAK_COUNT"]))
print df
较早版本
效率不高,因为我们需要遍历行和列,但适用于STREAK_COUNT内的任何值,并且更清晰易懂。
示例代码
import pandas as pd
df = pd.read_csv("sample.csv", index_col = 0)
#iterate over rows with index
for idx, (lab, row) in enumerate(df.iterrows()):
#get current STREAK_COUNT value
count = int(df.iloc[idx, 1])
#get previous positions based on count
pos = [i for i in range(idx,idx-count,-1)]
#count total
total = sum(df.iloc[pos, 0])
#create new column value based on total
func = lambda x : x if x !=0 else ''
df.loc[lab, "RESULT"] = func(total)
print df
结果
Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
MON TOTAL STREAK_COUNT RESULT
1/2/1992 1.123077 1 1.12308
2/3/1992 -1.296718 0
3/2/1992 -6.355612 2 -7.65233
4/1/1992 5.634692 0
5/1/1992 4.180605 2 9.8153
7/1/1992 -0.101016 0
8/3/1992 -0.706125 2 -0.807141
10/1/1992 0.368579 0
11/2/1992 3.822277 0
1/4/1993 2.233359 0
2/1/1993 15.219644 4 21.6439
3/1/1993 -2.647693 1 -2.64769
4/1/1993 1.599094 1 1.59909
>>>