web-dev-qa-db-fra.com

Compter les séparateurs dans les lignes CSV avec les pandas

J'ai un fichier csv comme suit:

name,age
something
tom,20

Et quand je le mets dans une base de données, cela ressemble à:

df = pd.read_csv('file', header=None)

     0           1
1    name        age
2    something   NaN
3    tom         20

Comment pourrais-je obtenir le nombre d'une virgule dans les données de lignes brutes. Par exemple, la réponse devrait ressembler à ceci:

# in pseudocode
df['_count_separators'] = len(df.raw_value.count(','))

     0           1      _count_separators
1    name        age   1
2    something   NaN   0
3    tom         20    1
14
David L

Très simplement, lisez vos données sous la forme d’une série de colonnes unique, puis divisez-les par virgule et concaténez-les avec le nombre de séparateurs.

# s = pd.read_csv(pd.compat.StringIO(text), sep=r'|', squeeze=True, header=None)
s = pd.read_csv('/path/to/file.csv', sep=r'|', squeeze=True, header=None)

pd.concat([
      s.str.split(',', expand=True), 
      s.str.count(',').rename('_count_sep')
   ], axis=1)

           0     1  _count_sep
0       name   age           1
1  something  None           0
2        tom    20           1

Une autre solution pour la concaténation consiste à join sur l'index (il s'agit d'une doublure nette):

s.str.split(',', expand=True).join(s.str.count(',').rename('_count_sep'))

           0     1  _count_sep
0       name   age           1
1  something  None           0
2        tom    20           1
10
coldspeed

Ce faisant 

df = pd.read_csv('file', header=None)
df2 = pd.read_csv('file', header=None,sep='|') # using another sep for read your csv again 

df2['0'].str.findall(',').str.len() # then one row into one cell , using str find 
0    1
1    0
2    1
3    5
Name: 0, dtype: int64

df['_count_separators']=df2['0'].str.findall(',').str.len()

Les données 

name,age
something
tom,20
something,,,,,somethingelse
8
Wen-Ben

Vous pouvez utiliser le module csv pour les délimiteurs de comptage. Il s’agit d’une solution en deux étapes, mais pas nécessairement inefficace par rapport à d’autres solutions en une étape.

from io import StringIO
import csv, pandas as pd, numpy as np

x = """name,age
something
tom,20"""

# replace StringIO(x) with open('file.csv', 'r')
with StringIO(x) as fin:
    delim_counts = np.fromiter(map(len, csv.reader(fin)), dtype=int)

# replace StringIO(x) with 'file.csv'
df = pd.read_csv(StringIO(x), header=None)
df['_count_separators'] = delim_counts - 1

print(df)

           0    1  _count_separators
0       name  age                  1
1  something  NaN                  0
2        tom   20                  1
1
jpp

Une ligne de code: len(df) - df[1].isna().sum()

0
Quang Hoang