Умное использование pd.concat
pd.concat({k: df.loc[v] for k, v in groups.items()}).sum(level=0)
data
a 22
b 8
c 2
ПРИМЕЧАНИЕ: Это волшебно работает для всех столбцов.
Предположим, у нас есть more_data
import random
random.seed(1)
df_len = 5
df = {
'idx':{i: i+1 for i in range(df_len)},
'data':{i:random.randint(1,11) for i in range(df_len)},
'more_data':{i:random.randint(1,11) for i in range(df_len)},
}
df = pd.DataFrame(df).set_index('idx')
Тогда
pd.concat({k: df.loc[v] for k, v in groups.items()}).sum(level=0)
data more_data
a 22 42
b 8 19
c 2 7
Но я бы придерживался большего Python: collections.defaultdict
from collections import defaultdict
results = defaultdict(int)
for k, V in groups.items():
for v in V:
results[k] += df.at[v, 'data']
pd.Series(results)
a 22
b 8
c 2
dtype: int64
Чтобы это работало с несколькими столбцами, мне нужно настроить defaultdict
немного по-другому:
from collections import defaultdict
results = defaultdict(lambda: defaultdict(int))
for k, V in groups.items():
for v in V:
for c in df.columns:
results[c][k] += df.at[v, c]
pd.DataFrame(results)
data more_data
a 22 42
b 8 19
c 2 7
Вот как это выглядело бы без defaultdict
, но с использованием метода setdefault
из объекта dict
.
results = {}
for k, V in groups.items():
for v in V:
for c in df.columns:
results.setdefault(c, {})
results[c].setdefault(k, 0)
results[c][k] += df.at[v, c]
pd.DataFrame(results)
data more_data
a 22 42
b 8 19
c 2 7