6

Pythonで入力データファイルをクリーンアップする必要があります。タイプミスにより、データフィールドに数値ではなく文字列が含まれる場合があります。文字列であるすべてのフィールドを識別し、パンダを使用してこれらをNaNで埋めたいと思います。また、それらのフィールドのインデックスをログに記録したいと思います。

最も大雑把な方法の1つは、すべてのフィールドをループして、それが数値であるかどうかを確認することですが、データが大きい場合、これには多くの時間がかかります。

私のcsvファイルには、次の表のようなデータが含まれています。

Country  Count  Sales
USA         1   65000
UK          3    4000
IND         8       g
SPA         3    9000
NTH         5   80000

....データにそのような行が60,000あると仮定します。

理想的には、行INDのSALES列の下の値が無効であることを確認したいと思います。これを効率的に行う方法について何か提案はありますか?

4

5 に答える 5

10

na_valuesに議論がありますread_csv

na_values:list-likeまたはdict、デフォルトNone
       NA/NaNとして認識する追加の文字列。dictが渡された場合、特定の列ごとのNA値

df = pd.read_csv('city.csv', sep='\s+', na_values=['g'])

In [2]: df
Out[2]:
  Country  Count  Sales
0     USA      1  65000
1      UK      3   4000
2     IND      8    NaN
3     SPA      3   9000
4     NTH      5  80000

を使用すると、列にNaNが含まれる行、または一連pandas.isnullの行のみを選択できます。'Sales''Country'

In [3]: df[pd.isnull(df['Sales'])]
Out[3]: 
  Country  Count  Sales
2     IND      8    NaN

In [4]: df[pd.isnull(df['Sales'])]['Country']
Out[4]: 
2    IND
Name: Country

すでにDataFrameにある場合は、apply数値である文字列を整数に変換するために使用できます(を使用str.isdigit)。

df = pd.DataFrame({'Count': {0: 1, 1: 3, 2: 8, 3: 3, 4: 5}, 'Country': {0: 'USA', 1: 'UK', 2: 'IND', 3: 'SPA', 4: 'NTH'}, 'Sales': {0: '65000', 1: '4000', 2: 'g', 3: '9000', 4: '80000'}})

In [12]: df
Out[12]: 
  Country  Count  Sales
0     USA      1  65000
1      UK      3   4000
2     IND      8      g
3     SPA      3   9000
4     NTH      5  80000

In [13]: df['Sales'] = df['Sales'].apply(lambda x: int(x) 
                                                  if str.isdigit(x)
                                                  else np.nan)

In [14]: df
Out[14]: 
  Country  Count  Sales
0     USA      1  65000
1      UK      3   4000
2     IND      8    NaN
3     SPA      3   9000
4     NTH      5  80000
于 2012-12-13T20:49:59.170 に答える
5
import os
import numpy as np
import pandas as PD

filename = os.path.expanduser('~/tmp/data.csv')
df = PD.DataFrame(
        np.genfromtxt(
            filename, delimiter = '\t', names = True, dtype = '|O4,<i4,<f8'))
print(df)

収量

  Country  Count  Sales
0     USA      1  65000
1      UK      3   4000
2     IND      8    NaN
3     SPA      3   9000
4     NTH      5  80000

売上のある国を見つけるために、次のNaNように計算できます

print(y['Country'][np.isnan(y['Sales'])])

:を生成しpandas.Seriesます

2    IND
Name: Country
于 2012-12-13T20:17:04.803 に答える
1

'sales'文字列をに変換してみてください。int整形式の場合は続行し、そうでない場合は、ValueErrorキャッチしてプレースホルダーと交換します。

bad_lines = []

with open(fname,'rb') as f:
    header = f.readline()
    for j,l in enumerate(f):
        country,count,sales = l.split()
        try:
            sales_count = int(sales)
        except ValueError:
            sales_count = 'NaN'
            bad_lines.append(j)
        # shove in to your data structure
        print country,count,sales_count

行を分割する行を編集する必要がある場合があります(例では、タブではなくスペースとしてコピーされます)。印刷行を、データでやりたいことと置き換えます。おそらく、パンダのNaNでも「NaN」を使用する必要があります。

于 2012-12-13T20:03:11.840 に答える
1
filename = open('file.csv')
filename.readline()

for line in filename:
    currentline = line.split(',')
    try:
        int(currentline[2][:-1])
    except:
        print currentline[0], currentline[2][:-1]

IND g

于 2012-12-13T23:56:51.157 に答える
1

正規表現を使用することを提案します。

import re

ss = '''Country  Count  Sales
USA   ,      3  , 65000
UK    ,      3  ,  4000
IND   ,      8  ,     g
SPA   ,     ju  ,  9000
NTH   ,      5  , 80000
XSZ   ,    rob  ,    k3'''

with open('fofo.txt','w') as f:
    f.write(ss)

print ss
print

delimiter = ','

regx = re.compile('(.+?(?:{0}))'
                  '(( *\d+?)| *.+?)'
                  '( *(?:{0}))'
                  '(( *\d+?)| *.+?)'
                  '( *\r?\n?)$'.format(delimiter))

def READ(filepath, regx = regx):
    with open(filepath,'rb+') as f:
        yield f.readline()
        for line in f:
            if None in regx.match(line).group(3,6):
                g2,g3,g5,g6 = regx.match(line).group(2,3,5,6)
                tr = ('%%%ds' % len(g2) % 'NaN' if g3 is None else g3,
                      '%%%ds' % len(g5) % 'NaN' if g6 is None else g6)
                modified_line = regx.sub(('\g<1>%s\g<4>%s\g<7>' % tr),line)
                print ('------------------------------------------------\n'
                       '%r with aberration\n'
                       '%r modified line'
                       % (line,modified_line))
                yield modified_line
            else:
                yield line

with open('modified.txt','wb') as g:
    g.writelines(x for x in READ('fofo.txt'))

結果

Country  Count  Sales
USA   ,      3  , 65000
UK    ,      3  ,  4000
IND   ,      8  ,     g
SPA   ,     ju  ,  9000
NTH   ,      5  , 80000
XSZ   ,    rob  ,    k3

------------------------------------------------
'IND   ,      8  ,     g\r\n' with aberration
'IND   ,      8  ,   NaN\r\n' modified line
------------------------------------------------
'SPA   ,     ju  ,  9000\r\n' with aberration
'SPA   ,    NaN  ,  9000\r\n' modified line
------------------------------------------------
'XSZ   ,    rob  ,    k3' with aberration
'XSZ   ,    NaN  ,   NaN' modified line
于 2012-12-14T00:03:12.830 に答える