Как рассчитать режим для поля в CSV-файле? - PullRequest
0 голосов
/ 03 января 2019

У меня есть этот текстовый файл:

Category;currency;sellerRating;Duration;endDay;ClosePrice;OpenPrice;Competitive?
Music/Movie/Game;US;3249;5;Mon;0,01;0,01;No
Music/Movie/Game;US;3249;5;Mon;0,01;0,01;No
Music/Movie/Game;US;3249;5;Mon;0,01;0,01;No
Music/Movie/Game;US;3249;5;Mon;0,01;0,01;No
Music/Movie/Game;US;3249;5;Mon;0,01;0,01;No
Music/Movie/Game;US;3249;5;Mon;0,01;0,01;No
Music/Movie/Game;US;3249;5;Mon;0,01;0,01;No
Automotive;US;3115;7;Tue;0,01;0,01;No
Automotive;US;3115;7;Tue;0,01;0,01;No
Automotive;US;3115;7;Tue;0,01;0,01;Yes

Я хочу рассчитать медиану для каждой категории. Так, например, я хочу рассчитать режим из sellerRating. Пока у меня есть это (потому что мне также нужно было вычислить средние значения, но мне удалось это сделать):

import csv
import locale
import statistics
from pprint import pprint, pformat

import locale

locale.setlocale(locale.LC_ALL, 'Dutch_Netherlands.1252')

avg_names = 'sellerRating', 'Duration', 'ClosePrice', 'OpenPrice'
averages = {avg_name: 0 for avg_name in avg_names}


num_values = 0
with open('bijlage.txt', newline='') as bestand:
     csvreader = csv.DictReader(bestand, delimiter=';')
     for row in csvreader:
        num_values += 1
        for avg_name in avg_names:
             averages[avg_name] += locale.atof(row[avg_name])


for avg_name, total in averages.items():
    averages[avg_name] = total / num_values

print('raw results:')
pprint(averages)

print()
print('Averages:')
for avg_name in avg_names:
    rounded = locale.format_string('%.2f', round(averages[avg_name], 2),
                           grouping=True)
    print('  {:<13} {:>10}'.format(avg_name, rounded))

Я пытался сделать:

from statistics import mode
mode(averages)

Но это не работает, и я застрял сейчас. Я новичок в Python, поэтому, если вы ответите на мою проблему, объясните мне, почему это должно быть ответом, чтобы я мог учиться.

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Вы можете сделать это так, пока вы вычисляете средние значения, которые используют defaultdict для хранения данных для вычисления режима каждой из категорий. Это полезно здесь, потому что позволяет создавать словарь списков, не зная, какими будут ключи, или сколько из них он продвигает, плюс он автоматически инициализирует значение каждого из них при первом обращении к пустому list как это используется здесь (defaultdict(list)).

Вы должны также использовать модуль статистики для вычисления средних значений, а не вычислять его самостоятельно, но я не изменил это, поскольку это не тема вашего вопроса.

import locale
import csv
from collections import defaultdict
import locale
import statistics

locale.setlocale(locale.LC_ALL, 'Dutch_Netherlands.1252')

avg_names = 'sellerRating', 'Duration', 'ClosePrice', 'OpenPrice'
averages = {avg_name: 0 for avg_name in avg_names}

seller_ratings = defaultdict(list)
durations = defaultdict(list)

num_values = 0
with open('bijlage.txt', newline='') as bestand:
     csvreader = csv.DictReader(bestand, delimiter=';')
     for row in csvreader:
        num_values += 1
        for avg_name in avg_names:
             averages[avg_name] += locale.atof(row[avg_name])

        # Add row values to corresponding category for fields of interest.
        seller_ratings[row['Category']].append(locale.atof(row['sellerRating']))
        durations[row['Category']].append(locale.atof(row['Duration']))

# Compute average of each field of interest.
for avg_name, total in averages.items():
    averages[avg_name] = total / num_values

print('Averages:')
for avg_name in avg_names:
    rounded = locale.format_string('%.2f', round(averages[avg_name], 2), grouping=True)
    print('  {:<13} {:>10}'.format(avg_name, rounded))


# Calculate modes for seller ratings.
seller_rating_modes = {}
for category, values in seller_ratings.items():
    try:
        seller_rating_modes[category] = statistics.mode(values)
    except statistics.StatisticsError:
        seller_rating_modes[category] = None  # No unique mode.

print()
print('Seller Rating Modes:')
for category, mode in seller_rating_modes.items():
    if mode is None:
        print('  {:<16} {:>10}'.format(category, 'No unique mode'))
    else:
        rounded = locale.format_string('%.2f', round(mode, 2), grouping=True)
        print('  {:<16} {:>10}'.format(category, rounded))


# Calculate modes for duration.
duration_modes = {}
for category, values in durations.items():
    try:
        duration_modes[category] = statistics.mode(values)
    except statistics.StatisticsError:
        duration_modes[category] = None  # No unique mode.

print()
print('Duration Modes:')
for category, mode in duration_modes.items():
    if mode is None:
        print('  {:<16} {:>10}'.format(category, 'No unique mode'))
    else:
        rounded = locale.format_string('%.2f', round(mode, 2), grouping=True)
        print('  {:<16} {:>10}'.format(category, rounded))
0 голосов
/ 03 января 2019

Панды - неплохая библиотека для этого.
pip install pandas

import pandas as pd
df = pd.read_csv('bijlage.csv', delimiter=';', decimal=',')  # 'bijlage.txt' in your case
sellerRating_median = df['sellerRating'].median()
print('Seller rating median: {}'.format(sellerRating_median)

Помимо median(), есть также mean() для расчета среднего
Вы также можете использовать mode() для расчета режима последовательности, но это возвращает список чисел, поэтому вам нужно будет использовать mode()[0], чтобы получить первое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...