Python 基于长格式的条件和追加行

Python 基于长格式的条件和追加行,python,pandas,dataframe,sum,pandas-groupby,Python,Pandas,Dataframe,Sum,Pandas Groupby,因此,我有一些样本数据如下: import pandas as pd objs = [ {'location':'US', 'fruit':'apple', 'time':'night', 'value': 1}, {'location':'US', 'fruit':'orange', 'time':'night', 'value': 3}, {'location':'US', 'fruit':'banana', 'time':'night', 'value': 1},

因此,我有一些样本数据如下:

import pandas as pd
objs = [
    {'location':'US', 'fruit':'apple', 'time':'night', 'value': 1},
    {'location':'US', 'fruit':'orange', 'time':'night', 'value': 3},
    {'location':'US', 'fruit':'banana', 'time':'night', 'value': 1},
    {'location':'EU', 'fruit':'apple', 'time':'night', 'value': 4},
    {'location':'EU', 'fruit':'orange', 'time':'night', 'value': 1},
    {'location':'EU', 'fruit':'banana', 'time':'night', 'value': 2},
    {'location':'US', 'fruit':'apple', 'time':'day', 'value': 5},
    {'location':'US', 'fruit':'orange', 'time':'day', 'value': 2},
    {'location':'US', 'fruit':'banana', 'time':'day', 'value': 3},
    {'location':'EU', 'fruit':'apple', 'time':'day', 'value': 6},
    {'location':'EU', 'fruit':'orange', 'time':'day', 'value': 2},
    {'location':'EU', 'fruit':'banana', 'time':'day', 'value': 1},
]
df = pd.DataFrame.from_records(objs)
它给出了一个长格式的数据帧,如:

   location   fruit   time  value
0        US   apple  night      1
1        US  orange  night      3
2        US  banana  night      1
3        EU   apple  night      4
4        EU  orange  night      1
5        EU  banana  night      2
6        US   apple    day      5
7        US  orange    day      2
8        US  banana    day      3
9        EU   apple    day      6
10       EU  orange    day      2
11       EU  banana    day      1
我希望,对于位置和时间的每一对/分组,根据水果列中的值有条件地求和value列。 具体而言:

我想对每个分组的苹果和橘子行求和,但不是香蕉行

生成下面的数据帧,并指定新行

   location      fruit   time  value
0        US      apple  night      1
1        US     orange  night      3
2        US     banana  night      1
3        US  NO_BANANA  night      4  <--
4        EU      apple  night      4
5        EU     orange  night      1
6        EU     banana  night      2
7        EU  NO_BANANA  night      5  <--
8        US      apple    day      5
9        US     orange    day      2
10       US     banana    day      3
11       US  NO_BANANA    day      7  <--
12       EU      apple    day      6
13       EU     orange    day      2
14       EU     banana    day      1
15       EU  NO_BANANA    day      8  <--

非常感谢您的帮助

如果每个组的条件相同,请先筛选,然后再分组:

subdf = df[df['fruit']!='banana'].groupby(['location', 'time']).sum().reset_index()
subdf['fruit'] = 'NO_BANANA'
df = pd.concat([df, subdf]).sort_values(['time', 'location'], ascending = False).reset_index(drop=True)
创建所需的组/聚合,不包括香蕉 原始数据的concat 根据需要进行排序/索引 输出 地方 水果 时间 价值 0 我们 没有香蕉 夜 4. 1. 我们 苹果 夜 1. 2. 我们 香蕉 夜 1. 3. 我们 橙色 夜 3. 4. 欧盟 没有香蕉 夜 5. 5. 欧盟 苹果 夜 4. 6. 欧盟 香蕉 夜 2. 7. 欧盟 橙色 夜 1. 8. 我们 没有香蕉 白天 7. 9 我们 苹果 白天 5. 10 我们 香蕉 白天 3. 11 我们 橙色 白天 2. 12 欧盟 没有香蕉 白天 8. 13 欧盟 苹果 白天 6. 14 欧盟 香蕉 白天 1. 15 欧盟 橙色 白天 2.
另一个选项是创建pivot_表

df=df.pivot_tableindex=[“位置”、“时间”、“水果”], 值=['value']。取消堆栈 价值 水果苹果香蕉橙 定位时间 欧盟第6天1 2 夜421 美国第5天3 2 第13晚 根据黑名单按列过滤水果:

遮盖水果以保存/排除 水果_黑名单=['香蕉'] cm=np.wheredf.columns.get_level_values1.isinfruits_黑名单,False,True 然后对过滤后的列按行求和:

df['value','NO_BANANA']=df.loc[:,cm].applynp.sum,axis=1 作为pd进口熊猫 将numpy作为np导入 黑名单 水果_黑名单=['香蕉'] 创建数据透视表 df=df.pivot_tableindex=[“位置”、“时间”、“水果”], 值=['value']。取消堆栈 遮盖水果以保存/排除 cm=np.wheredf.columns.get_level_values1.isinfruits_黑名单,False,True 按行求和 df['value','NO_BANANA']=df.loc[:,cm].applynp.sum,axis=1 堆栈和重置索引 df=df.堆叠“水果”\ .sort_值[时间、位置], 升序=假\ .reset_索引 展示 printdf.to_字符串 输出:

   location   time      fruit  value
0        US  night      apple      1
1        US  night     banana      1
2        US  night     orange      3
3        US  night  NO_BANANA      4
4        EU  night      apple      4
5        EU  night     banana      2
6        EU  night     orange      1
7        EU  night  NO_BANANA      5
8        US    day      apple      5
9        US    day     banana      3
10       US    day     orange      2
11       US    day  NO_BANANA      7
12       EU    day      apple      6
13       EU    day     banana      1
14       EU    day     orange      2
15       EU    day  NO_BANANA      8

这很有效,谢谢你!
df = pd.read_csv(io.StringIO("""   location   fruit   time  value
0        US   apple  night      1
1        US  orange  night      3
2        US  banana  night      1
3        EU   apple  night      4
4        EU  orange  night      1
5        EU  banana  night      2
6        US   apple    day      5
7        US  orange    day      2
8        US  banana    day      3
9        EU   apple    day      6
10       EU  orange    day      2
11       EU  banana    day      1"""), sep="\s+")

df = (pd.concat([df, df.loc[df.fruit.ne("banana")].groupby(["location","time"],as_index=False).agg({"value":"sum"}).assign(fruit="NO_BANANA")])
 .sort_values(["time","location","fruit"], ascending=[0,0,1])
 .reset_index(drop=True)
)
   location   time      fruit  value
0        US  night      apple      1
1        US  night     banana      1
2        US  night     orange      3
3        US  night  NO_BANANA      4
4        EU  night      apple      4
5        EU  night     banana      2
6        EU  night     orange      1
7        EU  night  NO_BANANA      5
8        US    day      apple      5
9        US    day     banana      3
10       US    day     orange      2
11       US    day  NO_BANANA      7
12       EU    day      apple      6
13       EU    day     banana      1
14       EU    day     orange      2
15       EU    day  NO_BANANA      8