#python
#python
Вопрос:
Имейте в виду, что я новичок в Python — у меня есть список со странами и населением в каждой области в файле csv.. выглядит так
['country', 'population']
['Usa', '1273']
['Usa', '4343']
['Usa', '1240']
['Uk', '7879']
['Uk', '3224']
['Uk', '4342']
['Tr', '6565']
['Tr', '7889']
['Tr', '1980']
Из этого списка мне нужно распечатать следующие данные (без использования pandas)
['country', 'avgPop']
['Usa', '2285']
['Uk', '5148']
['Tr', '5478']
до сих пор у меня есть отсортированный список, но я понятия не имею, как решить мою проблему.. помочь?
import csv
import requests
import operator
with requests.Session() as s:
download = s.get(CSV_URL)
decoded_content = download.content.decode('utf-8')
cr = csv.reader(decoded_content.splitlines(), delimiter=',')
my_list = list(cr)
sortedlist = sorted(my_list, key=operator.itemgetter(1), reverse=True)
with open ("openSomeNewFileDest.csv", 'w' , newline='') as f:
thewriter = csv.writer(f)
for row in sortedlist:
my_row = []
my_row.append(row[1])
my_row.append(row[9])
print(my_row)
Комментарии:
1. Как бы вы подошли к этой проблеме, если бы вам нужно было сделать это самостоятельно, вручную, на бумаге? Запишите это, а затем обобщите в коде.
2. (ping) Не могли бы вы, пожалуйста, помочь механике stackoverflow, приняв ответ, который вам понравился больше всего (если он действительно есть), чтобы авторы ответов не видели этот вопрос в своем активном списке 😉 спасибо за участие. Если ни один из ответов не был релевантным, пожалуйста, проигнорируйте этот пинг.
Ответ №1:
Будет ли что-то подобное работать для вас? data
Содержит список, который вы только что отсортировали.
data = [['country', 'population'],
['Usa', '1273'],
['Usa', '4343'],
['Usa', '1240'],
['Uk', '7879'],
['Uk', '3224'],
['Uk', '4342'],
['Tr', '6565'],
['Tr', '7889'],
['Tr', '1980']]
temp = {}
for i in range(1, len(data)):
if data[i][0] not in temp.keys():
temp[data[i][0]] = {
"sum": int(data[i][1]),
"count": 1
}
else:
temp[data[i][0]]["sum"] = int(data[i][1])
temp[data[i][0]]["count"] = 1
out = [["country", "avgPop"]]
for key in temp.keys():
avg = int(temp[key]["sum"] / temp[key]["count"])
out.append([key, avg])
print(out)
Вывод:
[['country', 'avgPop'],
['Usa', 2285],
['Uk', 5148],
['Tr', 5478]]
Комментарии:
1. Это идеально, я использовал его …. но заметил, что он удаляет элемент из массива, поэтому я изменил его на: for i in range(0, len(data)): тогда это сработало. Также обратите внимание, что я также удалил заголовки для своих.
2. @Steve237 Рад, что смог помочь! Мое решение использует
range(1, len(data))
, потому что оно предполагает, что данные содержат заголовки.
Ответ №2:
Я полагаю, это делает именно то, о чем вы просили:
import csv
index = {}
with open('/tmp/data.csv') as f:
cr = csv.reader(f)
next(cr) # skip header row
for row in cr:
index.setdefault(row[0], []).append(int(row[1]))
print("['country', 'avgPop']")
for c, v in index.items():
print("['{}', '{}']".format(c, int(sum(v) / len(v))))
Входной файл CSV:
country, population
Usa, 1273
Usa, 4343
Usa, 1240
Uk, 7879
Uk, 3224
Uk, 4342
Tr, 6565
Tr, 7889
Tr, 1980
Результат:
['country', 'avgPop']
['Usa', '2285']
['Uk', '5148']
['Tr', '5478']
Комментарии:
1. Спасибо за вашу помощь!! что, если я хочу вывести данные из более чем 2 столбцов? есть ли какой-нибудь способ сделать это с помощью setDeafault или мне нужно заменить его каким-либо другим вариантом?
2. Вы можете делать все, что хотите — setDefault — это как раз то, что нужно для того, что вы хотели сделать в первую очередь. Вам нужно определить, какой новый результат вы хотите, и только тогда вы можете подумать о том, как вы собираетесь получить этот результат. — каким будет следующий столбец?
Ответ №3:
Вот как это делается идиоматически (отсюда лучшая читаемость, наименьшее количество ошибок и лучшая производительность процессора / памяти) с помощью базовых инструментов:
from itertools import groupby
def get_avg(vs):
sum_vs = 0
num_vs = 0
for v in vs:
sum_vs = v
num_vs = 1
return sum_vs / num_vs
def group_by(rows, key):
return groupby(sorted(rows, key=key), key=key)
rows = csv.reader(decoded_content.splitlines(), delimiter=',')
for country, rows in group_by(rows, lambda row: row[0]):
print(country, get_avg(float(row[1]) for row in rows))
Вы используете sorted
и itertools.groupby
с тем же лямбда, что удобно дает вам сгруппированные строки.