因此,我已经四处张望,但找不到该问题的答案。我很抱歉是否确实在那里。
我有一个看起来像这样的DF:
a = pd.DataFrame({'Name': ['apple', 'banana', 'orange', 'apple', 'banana','orange'],
'Units': [2,4,6,5,4,3]})
我还有一个这样的列表列表:
b = [['apple', 'banana'],['orange']]
目标是将苹果和香蕉分成1列,将桔子分为另一列,并将它们各自的单位相加。列中的变量将显示为子列表中的第一项。 (任何子列表都不会重复)。
这是我希望输出df看起来像的样子:
output = pd.DataFrame({'Name': ['apple', 'orange'],
'Units': [15, 9]})
我现在在这里:
for fruit in a['Name']:
for sublist in b:
if fruit in sublist:
pd.concat([XYZ,
pd.DataFrame({'Name': sublist[0], 'Units': a[a.Name == fruit]['Units'].sum(), index=[0})],
axis=1)
XYZ是一个空数据框,其列=名称和我要用结果填充的单位。当水果在子列表中以及其单位的总和时,我真的不太了解如何创建数据框。
有什么想法吗? :D
编辑:子列表的范围为1到300个项目。这里的代码只是一个更大的数据处理问题的MWE。抱歉,没有提到这一点。
答案 0 :(得分:1)
实际上,您可以在一行中完成此操作:
sum_a = a.replace({"banana": "apple"}).groupby("Name", as_index=False).sum()
答案 1 :(得分:1)
IIUC,最好重新创建对象,而不是更改原始df,因为replace
仍然会丢失有关apple
的信息,因为您将苹果替换为香蕉。因此,输出结果会仅包含有关apple
或banana
d={','.join(x):a.loc[a.Name.isin(x),'Units'].sum() for x in b }
pd.Series(d)
apple,banana 15 # here you do not losing the information of each items in the list
orange 9
dtype: int64
答案 2 :(得分:0)
使用pd.Series.isin
和布尔索引:
pd.DataFrame([(l[0], a.Units[a.Name.isin(l)].sum()) for l in b], columns=['Name', 'Units'])
Name Units
0 apple 15
1 orange 9
答案 3 :(得分:0)
另一种解决方案是制作一个同时返回名称和总和值的函数。
from operator import itemgetter
first = itemgetter(0)
def make_rows(cols, df):
for col in cols:
name = first(col)
val = df.loc[df.Name.str.contains('|'.join(col), regex=True), 'Units'].sum()
yield name, val
df1 = pd.DataFrame(make_rows(b, a), columns=a.columns)
print(df1)
Name Units
0 apple 15
1 orange 9
另外也是如此:
from functools import partial
def make_rows(df, col):
name = first(col)
val = df.loc[df.Name.str.contains('|'.join(col), regex=True), 'Units'].sum()
return name, val
p = partial(make_rows, a)
pd.DataFrame(list(map(p, b)), columns=a.columns)
Name Units
0 apple 15
1 orange 9