2016-03-04 3 views
0

У меня есть CSV-файл, который выглядит следующим образом:Python Добавления нескольких точек данных в Словаре из CSV файла

CountryCode, NumberCalled, CallPrice, CallDuration 
BS,+1234567,0.20250,29 
BS,+19876544,0.20250,1 
US,+121234,0.01250,4 
US,+1543215,0.01250,39 
US,+145678,0.01250,11 
US,+18765678,None,0 

Я хочу, чтобы иметь возможность анализировать файл для работы некоторых статистических данных из данных:

CountryCode, NumberOfTimesCalled, TotalPrice, TotalCallDuration 
US, 4, 1.555, 54 

на данный момент у меня есть Dict установка Thats:

CalledStatistics = {} 

Когда я прочитал каждую строку из CSV, Что лучше т o поместить данные в dict? :

CalledStatistics['CountryCode'] = {'CallDuration', 'CallPrice', 'NumberOfTimesCalled'} 

Будет добавив вторую линию США перезаписать первую строку или бы данные будут добавлены на основе ключа «COUNTRYCODE»?

+0

В чем вопрос? У вас есть словарь, и каждый раз, когда вы читаете CSV, код страны всегда будет перезаписываться, поэтому вы получите ключ с ключами (BS, US) и значения = самая последняя запись, т. Е. Перезаписанные данные. – Seekheart

+0

Вы действительно хотите назначить набор 'CalledStatistics ['CountryCode']'? – MattDMo

+0

В словаре KEY - это уникальное значение, поэтому да, сделав его таким образом, он перепишет VALUE. Вы просто назначаете новое VALUE уже существующему KEY (US). – catalesia

ответ

2

Каждый из этих вызовов:

CalledStatistics['CountryCode'] = {'CallDuration', 'CallPrice', 'NumberOfTimesCalled'} 

будет перезаписывать вызов раньше.

Для того, чтобы рассчитать сумму, которую вам нужно, вы можете использовать опцию dicts. Как в цикле for, где у вас есть данные в этих переменных: country_code, call_duration, call_price и где вы будете хранить данные в собранной_статистике: (EDIT: добавлена ​​первая строка, чтобы превратить call_price в 0, если она записана как None в данных, этот фрагмент кода предназначен для работы с согласованными данными, например, целыми числами, если есть, возможно, другие типы данных, их нужно преобразовать в целые числа [или любые числа того же типа], прежде чем python сможет их суммировать)

call_price = call_price if call_price != None else 0 

if country_code not in collected_statistics: 
    collected_statistics[country_code] = {'CallDuration' : [call_duration], 
              'CallPrice' : [call_price]} 
else: 
    collected_statistics[country_code]['CallDuration'] += [call_duration] 
    collected_statistics[country_code]['CallPrice'] += [call_price] 

и после цикла, для каждого COUNTRY_CODE:

number_of_times_called[country_code] = len(collected_statistics[country_code]['CallDuration'] 

total_call_duration[country_code] = sum(collected_statistics[country_code]['CallDuration']) 
total_price[country_code] = sum(collected_statistics[country_code]['CallPrice']) 

ОК, так что, наконец, вот полный УНР

#!/usr/bin/env python3 

import csv 
import decimal 

with open('CalledData', newline='') as csvfile: 
    csv_r = csv.reader(csvfile, delimiter=',', quotechar='|') 

    # btw this creates a dict, not a set 
    collected_statistics = {} 

    for row in csv_r: 

     [country_code, number_called, call_price, call_duration] = row 

     # Only to avoid the first line, but would be better to have a list of available 
     # (and correct) codes, and check if the country_code belongs to this list: 
     if country_code != 'CountryCode': 

      call_price = call_price if call_price != 'None' else 0 

      if country_code not in collected_statistics: 
       collected_statistics[country_code] = {'CallDuration' : [int(call_duration)], 
                 'CallPrice' : [decimal.Decimal(call_price)]} 
      else: 
       collected_statistics[country_code]['CallDuration'] += [int(call_duration)] 
       collected_statistics[country_code]['CallPrice'] += [decimal.Decimal(call_price)] 


    for country_code in collected_statistics: 
     print(str(country_code) + ":") 
     print("number of times called: " + str(len(collected_statistics[country_code]['CallDuration']))) 
     print("total price: " + str(sum(collected_statistics[country_code]['CallPrice']))) 
     print("total call duration: " + str(sum(collected_statistics[country_code]['CallDuration']))) 

используя CalledData как файл, имеющий тот же контент, при условии, что выводит:: король обработки примера вы дали сценарий

$ ./test_script 
BS: 
number of times called: 2 
total price: 0.40500 
total call duration: 30 
US: 
number of times called: 4 
total price: 0.03750 
total call duration: 54 
+0

Это не сработает, потому что будет ** TypeError ** из-за наличия значения ** None ** в последней строке. Но это хорошо. – catalesia

+1

Действительно. Я думаю, мы можем предположить, что цена Ничего не может быть обработана так, как если бы она была равна нулю. Таким образом, данные должны быть обработаны до их использования. Я редактирую свой пост, чтобы отразить это. – zezollo

+0

Не так просто, как вы думаете :) Мы не знаем всех деталей. Чем сложнее дело, тем больше, ну, он усложняется! Вы протестировали его? Это работает? Представьте, что где-то в файле кто-то поставил «пять» вместо 5;) – catalesia

0

Словари могут содержать списки и списки словарей, так что вы можете достичь желаемую структуру следующим образом:

CalledStatistics['CountryCode'] =[ { 
    'CallDuration':cd_val, 
    'CallPrice':cp_val, 
    'NumberOfTimesCalled':ntc_val } ] 

Затем вы можете добавить значения, как это:

for line in lines: 
    parts = line.split(',') 
    CalledStatistics[parts.pop(0)].append({ 
     'CallDuration':parts[0], 
     'CallPrice':parts[1], 
     'NumberOfTimesCalled':parts[2] }) 

Приведя каждый countryCode список, вы можете добавить столько уникальных dicts, сколько хотите для каждого countryCode.

Метод pop(i) возвращает значение и изменяет список, так что все, что остается, - это данные, которые вы хотите для значений dict. Вот почему мы публикуем индекс 0 и добавляем индекс 0 - 2 к dict.

0

Ваш подход может быть несколько иным. Просто прочитайте файл, сделайте его списком (readlines.strip ("\ n"), split (",").

Забудьте о первой и последней (скорее всего, пустой, тест). Затем вы можете сделать dict с использованием примера @zezollo и просто добавить значения с помощью ключа dict, который вы создали. Убедитесь, что все значения, которые вы добавляете, после того, как вы составили список списков, являются одним и тем же типом.

Ничто как тяжелая работа, вы будете помнить, что дело на долго;)

тест, тест, тест на ложных примерах. И прочитайте справку и документы Python. Это великолепно.

Смежные вопросы