मेरे पास नीचे की तरह सीएसवी फ़ाइल है

फ़ाइल1

A B
1 2
3 4

करें 2

A B
1 2

फ़ाइल3

A B
1 2
3 4
5 6

मैं सभी csv फ़ाइल में पंक्तियों को गिनना चाहता हूँ

मैंने कोशिश की

f=pd.read_csv(file1)

f.shape

लेकिन जब मेरे पास बहुत सी csv फ़ाइल होती है, तो इसमें बहुत अधिक समय लगता है।

मैं नीचे जैसा परिणाम प्राप्त करना चाहता हूं

      rows
file1  2
file2  1
file3  3

मैं यह परिणाम कैसे प्राप्त कर सकता हूं?

2
Heisenberg 10 अप्रैल 2017, 13:32

5 जवाब

सबसे बढ़िया उत्तर

आप सभी फाइलों में से dict length बना सकते हैं और फिर DataFrame के लिए Seriesm to_frame:

import glob
import pandas as pd

files = glob.glob('files/*.csv')

d = {f: sum(1 for line in open(f)) for f in files}

print (pd.Series(d))

print (pd.Series(d).rename('rows').rename_axis('filename').reset_index())

open फ़ाइल के ठीक से बंद होने की गारंटी नहीं देता है, इसलिए दूसरा समाधान:

def file_len(fname):
    with open(fname) as f:
        for i, l in enumerate(f):
            pass
    return i + 1

d = {f: file_len(f) for f in files}
6
jezrael 10 अप्रैल 2017, 14:31

* निक्स सिस्टम में और यदि आप इसे पायथन के बाहर कर सकते हैं:

wc -l *.csv

तरकीब करनी चाहिए।

2
efajardo 10 अप्रैल 2017, 23:05

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

नीचे दिया गया कोड rawincount() के बाद थोड़ा तेज़ चलता है और उन अंतिम पंक्तियों को भी गिनता है जिनमें पंक्ति के अंत में '\n' नहीं होता है (एक समस्या rawincount() है):

import glob, subprocess, pandas
files = glob.glob('files/*.csv') 
d = {f: subprocess.getoutput("sed -n '$=' " + f) for f in files}
print(pandas.Series(d))

पी.एस. यहाँ कुछ समय मैंने बड़ी टेक्स्ट फ़ाइलों के एक सेट पर चलाया है (39 फाइलें 3.7 जीबीटी के कुल आकार के साथ, लिनक्स मिंट 18.1, पायथन 3.6)। यहां प्रस्तावित wc -l *.csv पद्धति का समय आकर्षक है:

    Results of TIMING functions for getting number of lines in a file:
    -----------------------------------------------------------------
            getNoOfLinesInFileUsing_bash_wc :  1.04  !!! doesn't count last non empty line
          getNoOfLinesInFileUsing_bash_grep :  1.59
  getNoOfLinesInFileUsing_mmapWhileReadline :  2.75
           getNoOfLinesInFileUsing_bash_sed :  3.42
 getNoOfLinesInFileUsing_bytearrayCountLF_B :  3.90  !!! doesn't count last non empty line
          getNoOfLinesInFileUsing_enumerate :  4.37
      getNoOfLinesInFileUsing_forLineInFile :  4.49
  getNoOfLinesInFileUsing_sum1ForLineInFile :  4.82      
 getNoOfLinesInFileUsing_bytearrayCountLF_A :  5.30  !!! doesn't count last non empty line
     getNoOfLinesInFileUsing_lenListFileObj :  6.02
           getNoOfLinesInFileUsing_bash_awk :  8.61
2
Claudio 11 अप्रैल 2017, 04:04

बहुत बड़े csv के साथ काम करते समय अब ​​तक प्रदान किए गए समाधान सबसे तेज़ नहीं हैं। साथ ही, सूची बोध में open() का उपयोग करने से यह गारंटी नहीं मिलती कि फ़ाइल ठीक से बंद हो जाएगी जैसे कि with का उपयोग करते समय (यह देखें प्रश्न)। तो इसे गति के लिए this question की अंतर्दृष्टि के साथ संयोजित करें:

from itertools import takewhile, repeat

def rawincount(filename):
    with open(filename, 'rb') as f:
        bufgen = takewhile(lambda x: x, (f.raw.read(1024*1024) for _ in repeat(None)))
        return sum(buf.count(b'\n') for buf in bufgen)

और @jezrael द्वारा प्रदान किए गए समाधान को लागू करना:

import glob
import pandas as pd

files = glob.glob('files/*.csv')
d = {f: rawincount(f) for f in files}
df = pd.Series(d).to_frame('rows')
1
Community 23 मई 2017, 14:54

ये कोशिश करें,

यह प्रत्येक प्रविष्टि को फ़ाइल नाम और पंक्तियों की संख्या के साथ जोड़ता है और कॉलम में उपयुक्त लेबल होते हैं:

import os      
df = pd.DataFrame(columns=('file_name', 'rows'))
for index,i in enumerate(os.listdir('.')):
    df.loc[index] = [i,len(pd.read_csv(i).index)]
1
Claudio 11 अप्रैल 2017, 00:16