2014-05-05 3 views
6

मैं के रूप में डेटा के स्तंभों के शीर्ष पर हेडर के साथ एक csv फ़ाइल है dict में सीएसवी मूल्यों को पढ़ने के लिए ...अधिकांश pythonic तरीका सूचियों

<Header1>, <Header2>, ... ,<HeaderN> 
<data11> , <data12> , ... ,<data1N> 
<data21> , <data12> , ... ,<data2N> 
...  , ... , ... , ... 
<dataM1> , <dataM2> , ... ,<dataMN> 

(यानी मानक सारणीबद्ध डेटा)

जब DictReader साथ यह पढ़ रहा एक नेस्टेड लूप का उपयोग कर रहा

f = <path_to_some_csv_file.csv> 
dr = csv.DictReader(open(f)) 
    dict_of_lists = dr.next() 
    for k in dict_of_lists.keys(): 
     dict_of_lists[k] = [dict_of_lists[k]] 
    for line in dr: 
     for k in dict_of_lists.keys(): 
      dict_of_lists[k].append(line[k]) 

पहले लूप के रूप में पंक्ति संबंधित कुंजी में सूची में पढ़ा में आइटम संलग्न करने के लिए करने के लिए dict में सभी मान सेट खाली सूची अगला सीएसवी फ़ाइल से पढ़ने वाली प्रत्येक पंक्ति पर लूप करता है, जिससे डिक्ट्रेडर कुंजी-मानों का एक नियम बनाता है। आंतरिक लूप संबंधित कुंजी मान से मेल खाने वाली सूची को जोड़ता है, इसलिए मैं डिक्ट की वांछित सूची के साथ हवा में जाता हूं। मैं इसे काफी बार लिखना चाहता हूं।

मेरा सवाल यह है कि, नेस्टेड लूप के बिना फ़ंक्शंस में निर्मित या बेहतर डेटाियोम या इस डेटा संरचना को स्टोर करने का एक वैकल्पिक तरीका है, जिससे मैं पूछताछ करके एक अनुक्रमणीय सूची वापस कर सकता हूं, ऐसा करने का एक और पाइथोनिक तरीका है। एक महत्वपूर्ण मूल्य के साथ? यदि ऐसा है तो कॉलम को सामने वाले डेटा को प्रारूपित करने का एक तरीका भी है? (एक MWE के लिए बस उपरोक्त डेटा को एक टेक्स्ट फ़ाइल में कॉपी करें और इसे कोड के माध्यम से चलाएं) अग्रिम धन्यवाद!

dict_of_lists = merge_with(list, *csv.DictReader(open(f))) 

केवल stdlib का उपयोग करना, एक defaultdict कोड कम करता है:

+0

'() dict_of_lists.keys में कश्मीर के लिए: -'> 'dict_of_lists में कश्मीर के लिए:' –

उत्तर

5

आप भंडारण कर रहे हैं किस प्रकार का डेटा पर निर्भर करता है और यदि आप numpy उपयोग करने के साथ ठीक कर रहे हैं, एक अच्छा तरीका यह करने के लिए numpy.genfromtxt साथ हो सकता है:

import numpy as np 
data = np.genfromtxt('data.csv', delimiter=',', names=True) 

क्या यह कर देगा एक numpy बनाने है Structured Array, जो हेडर नाम से डेटा पूछताछ के लिए एक अच्छा इंटरफ़ेस प्रदान करता है (यदि आपके पास हेडर पंक्ति है तो names=True का उपयोग करना सुनिश्चित करें)।

उदाहरण, यह देखते हुए data.csv युक्त

a,b,c 
1,2,3 
4,5,6 
7,8,9 

फिर आप तत्वों के साथ उपयोग कर सकते हैं:

>>> data['a']  # Column with header 'a' 
array([ 1., 4., 7.]) 
>>> data[0]   # First row 
(1.0, 2.0, 3.0) 
>>> data['c'][2]  # Specific element 
9.0 
>>> data[['a', 'c']] # Two columns 
array([(1.0, 3.0), (4.0, 6.0), (7.0, 9.0)], 
     dtype=[('a', '<f8'), ('c', '<f8')]) 

genfromtext भी एक तरीका प्रदान करता है, जैसा कि आप का अनुरोध किया, "डेटा को फ़ॉर्मेट करने स्तंभ द्वारा किया जाता जा रहा है ऊपर सामने। "

कन्वर्टर्स: चर, वैकल्पिक

कार्यों कि एक मूल्य के लिए एक स्तंभ का डेटा परिवर्तित का सेट। कन्वर्टर्स का उपयोग गायब डेटा के लिए डिफ़ॉल्ट मान प्रदान करने के लिए भी किया जा सकता है: कन्वर्टर्स = {3: लैम्ब्डा एस: फ्लोट (एस या 0)}।

1

यदि आप एक तीसरे पक्ष के पुस्तकालय का उपयोग करने को तैयार हैं, तो Toolz से merge_with समारोह इस पूरे ऑपरेशन एक एक लाइनर बनाता है दोहराव:

from collections import defaultdict 
import csv 

f = 'test.csv' 

dict_of_lists = defaultdict(list) 
for record in DictReader(open(f)): 
    for key, val in record.items(): # or iteritems in Python 2 
     dict_of_lists[key].append(val) 

यदि आपको अक्सर ऐसा करने की ज़रूरत है, तो इसे एक समारोह में कारक बनाएं, उदाहरण के लिए transpose_csv

-1

आप अपने इरादे और अधिक स्पष्ट बनाने के लिए dict का उपयोग करें और comprehensions सेट कर सकते हैं:

dr=csv.DictReader(f) 
data={k:[v] for k, v in dr.next().items()}    # create the initial dict of lists 
for line_dict in dr: 
    {data[k].append(v) for k, v in line_dict.items()} # append to each 

आप Alex Martelli's method उपयोग कर सकते हैं अजगर में सूचियों की एक सूची समतल iterators का एक इटरेटर है, जो आगे कम कर देता है समतल पहले फार्म के लिए:

dr=csv.DictReader(f) 
data={k:[v] for k, v in dr.next().items()} 
{data[k].append(v) for line_dict in dr for k, v in line_dict.items()} 

पायथन 2.x पर, {}.iteritems बनाम {}.items() का उपयोग कर अगर अपनी csv फ़ाइल बड़े आकार का है पर विचार करें।


इसके अलावा उदाहरण:

Header 1,Header 2,Header 3 
1,2,3 
4,5,6 
7,8,9 

अब आप एक नाव या पूर्णांक में बदल जाती प्रत्येक मान की सूचियों का एक dict चाहते लगता है:

इस csv फ़ाइल मान लें। आप कर सकते हैं:

def convert(s, converter): 
    try: 
     return converter(s) 
    except Exception: 
     return s  

dr=csv.DictReader(f) 
data={k:[convert(v, float)] for k, v in dr.next().items()} 
{data[k].append(convert(v, float)) for line_dict in dr for k, v in line_dict.items()} 

print data 
# {'Header 3': [3.0, 6.0, 9.0], 'Header 2': [2.0, 5.0, 8.0], 'Header 1': [1.0, 4.0, 7.0]} 
+0

यह आम तौर पर pythonic नहीं एक समझ (इस मामले में एक सेट समझ का उपयोग करने, सभी की है चीजें) एक लूप करने के लिए। बस इसके बजाय स्पष्ट लूप लिखें, यह अधिक प्राकृतिक है और आप जो कर रहे हैं उसके बारे में अधिक स्पष्ट है। – Blckknght

संबंधित मुद्दे