Допустим, у меня есть 2D-список:
mylist = [[3,4,5,'x'],
[6,1,4,'x'],
[4,7,9,'y'],
[0,4,3,'y'],
[5,1,7,'z']]
Как бы я суммировал второй столбец, где четвертые элементы одинаковы (буквы)? В настоящее время я выделил четвертые элементы в список, избегая дублирования, с помощью:
newlist = list(set([r[3] for r in mylist]))
Который возвращает список ['z', 'y', 'x']
Я хочу получить его в формате вроде [['x', a], ['y', b]..]
или в словаре, например {'x':a,...}
Где a
- сумма второго столбца, где mylist[3]='x'
, который будет равен 4 + 1, а b
такой же, но с y
, и будет равен 7 + 4. Так что этот пример будет выводить [['x', 5], ['y', 11], ['z', 1]]
Каков был бы лучший способ сделать это? Или numpy / pandas справятся с этим лучше?
5 ответов
Это должно быть сделано, я использую zip
mylist = [[3,4,5,'x'],
[6,1,4,'x'],
[4,7,9,'y'],
[0,4,3,'y'],
[5,1,7,'z']]
#Zip all elements in the list
res = list(zip(*mylist))
#Zip the second column and character array
arr = list(zip(res[1], res[3]))
#[(4, 'x'), (1, 'x'), (7, 'y'), (4, 'y'), (1, 'z')]
dct = {}
#Calculate the sum
for num, key in arr:
dct.setdefault(key,0)
dct[key]+=num
print(dct)
#{'x': 5, 'y': 11, 'z': 1}
#Convert dict to list
li = []
for k, v in dct.items():
li.append([k,v])
print(li)
На выходе будет
[['x', 5], ['y', 11], ['z', 1]]
Еще одним способом может быть использование defaultdict
.
from collections import defaultdict
mylist = [
[3,4,5,'x'],
[6,1,4,'x'],
[4,7,9,'y'],
[0,4,3,'y'],
[5,1,7,'z']
]
d = defaultdict(int)
for l in mylist:
d[l[3]] += l[1]
# d: defaultdict(<class 'int'>, {'x': 5, 'y': 11, 'z': 1})
# dict(d) to convert to regular dict
Я предпочитаю панд для этой цели:
import pandas as pd
mylist = [[3,4,5,'x'],
[6,1,4,'x'],
[4,7,9,'y'],
[0,4,3,'y'],
[5,1,7,'z']]
df = pd.DataFrame(mylist)
Это дает:
print(df)
0 1 2 3
0 3 4 5 x
1 6 1 4 x
2 4 7 9 y
3 0 4 3 y
4 5 1 7 z
Работа с группой панд:
print(df.groupby(3).sum())
0 1 2
3
x 9 5 9
y 4 11 12
z 5 1 7
print(df.groupby(3).sum()[1].to_dict())
{'x': 5, 'y': 11, 'z': 1}
Это оно
Это может быть сделано путем зацикливания на каждом элементе в вашем списке, проверки 4-го места для x или y и добавления некоторого промежуточного итога:
mylist = [[3,4,5,'x'],
[6,1,4,'x'],
[4,7,9,'y'],
[0,4,3,'y'],
[5,1,7,'z']]
x_total = 0
y_total = 0
for i in mylist:
if i[3] == "y":
y_total += i[1]
if i[3] == 'x':
x_total += i[1]
print("x: ",x_total)
print("y: ",y_total)
Вы можете использовать счетчик (из коллекции):
from collections import Counter
result = Counter()
for r in mylist:
result[r[3]] += r[1]
Вы также можете сделать это в одной строке:
result = Counter( r[3] for r in mylist for _ in range(r[1]) )
Или без использования счетчика:
result = dict()
for _,value,_,key in map(tuple,mylist): # for r in mylist
result[key] = result.get(key,0) + value # result[r[3]]=result.get(r[3],0)+r[1]
Или
result = { r[3]:sum(v[1] for v in mylist if v[3]==r[3]) for r in mylist }
обратите внимание, что циклы for будут работать быстрее, чем однострочные
Похожие вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.