Поиск по блогу

вторник, 7 апреля 2015 г.

Первый рабочий пример конкатенции таблиц с преобразованием форматов столбцов object -> float

Файлы таблиц "Brandt 2014y 2013y 1413y 2014m 2013m 1413m Datem" Визуальный тест pandasd.read_csv - как распечатать все файлы из папки при помощи PDB. Считать данные в кавычках, с разделителями разрядов, привести все пропуски данных к единому виду - Nan, перевести строку в число...
Не уверен, что это лучший варинат, но пока не знаю, как поступить иначе при таком уровне неопределенности. Формат исходных (ежемесячные данные) файлов менялся за год несколько раз. Там то появлялись запятые вместо пробелов - разделителей разрядов, то менялось количество столбцов... Пришлось парсеры перенастраивать и менять... Файлы короткие, распечатаю ка я их все за год и дело с концом... Нет, не так все просто, надо куда-то сохранить полученный файл...

In [1]:
import os
import pandas as pd
In [ ]:
Фрагмент со всеми неоднородностями (почти)
In [ ]:
"Dodge*******","-","10","-","26","184","-86%",
"Izh","-","31","-","19","678","-97%",
"FAW","n/a","513","-","2,164","3,739","-42%",
"cars","9,322","12,625","-26.2%","103,119","129,847","-20.6%",
"vans","973","1,310","-25.7%","10,381","12,882","-19.4%",
"BENZ cars","4,240","4,157","2.0%","40,673","36,200","12.4%",
"BENZ vans","1,178","489","140.9%","6,795","3,911","73.7%",

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

In [ ]:
"-", "n/a"
"12,625" - coma
'"'

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

In [2]:
months = ['january', 'febrary', 'march', 'april', 'may', 'jun',
        'july', 'august','september', 'october','november', 'december']
    
dict = {'january':'31-1', 'febrary':'28-2', 'march':'31-1',
        'april':'30-4', 'may':'31-5', 'june':'30-6',
        'july':'31-7', 'august':'31-8','september':'30-9', 
        'october':'31-10','november':'30-11', 'december':'31-12'}
In [87]:
for csvfile in os.listdir(DIRPATH):
    if csvfile.startswith('eng_car-sales-in'):
        print  csvfile
eng_car-sales-in-april-2014.csv
eng_car-sales-in-august-2014.csv
eng_car-sales-in-december-2014.csv
eng_car-sales-in-july-2014.csv
eng_car-sales-in-june-2014.csv
eng_car-sales-in-may-2014.csv
eng_car-sales-in-november-2014.csv
eng_car-sales-in-october-2014.csv
eng_car-sales-in-september-2014.csv
In [3]:
def addDatem(csvfile):
    # Parse month name from filename
    namen = csvfile.split('-')[3]            # 'april' for example
    
    # Replace strings with dict     'april':'30-4', 
    datstr = dict[namen] + '-2014'  # '30-4-2014'    
    return datstr
In [81]:
csvfile = 'eng_car-sales-in-april-2014.csv'
addDatem(csvfile)
Out[81]:
'30-4-2014'

Конкатенция всех файлов в один объект DataFrame

In [4]:
pdall =  pd.DataFrame()
In [5]:
def concatall(pdall, pdtemp):
    #Concat month dataframes to pdall
    pdall = pd.concat([pdall, pdtemp], ignore_index=True)
    return pdall

А убрать звездочки (не знаю, нужно ли здесь это делать), занк % и перевести в float два столбца нужно будет уже в общем фрейме

In [ ]:
***
"73.7%" -> 73.7 (float)
"-97%"  -> 97   (Int) ?

Особенности в файлах

In [ ]:
Часть имени для фильтра     Да
Строки                      В первом файле убрать строку заголовков !!!!!
Количество строк            Неодинаковое число строк в фалах
Пропуск плохихи строк       error_bad_lines=False
Nan                         na_values=['-','n/a']
CSV                         quotechar='"', sep=',', 
Разделитель разрядов        thousands=','

Файлы в папке

In [6]:
# Path to dir with files
DIRPATH = '/media/MYLINUXLIVE/Documents/Xpdf/aerbu_2014_all_csv/1aug2/'

# Insert my columns names in Dataframe objects
COLNAMES =['Brandt', '2014y', '2013y', '1413y', '2014m', '2013m', '1413m', 'Datem']

# Filter only filenames with
filterfilenames = 'eng_car-sales-in'
In [ ]:
# Для длинных файлов можно использовать
print (csvfile)
pdtemp.head(5)
print '...'
pdtemp.tail(3)
In [8]:
import pdb; pdb.set_trace()
pdall =  pd.DataFrame()
for csvfile in os.listdir(DIRPATH):
    if csvfile.startswith(filterfilenames):
        csvfile_path = os.path.join(DIRPATH, csvfile)
        
        pdtemp = pd.read_csv(csvfile_path, error_bad_lines=False, \
                             names=COLNAMES, na_values=['-','n/a'], \
                             quotechar='"', sep=',', thousands=',')
        pdtemp['Datem'] = addDatem(csvfile)
        pdall = pd.concat([pdall, pdtemp], ignore_index=True)
        
        #print (csvfile)
        #print (pdtemp)
print(pdall)
--Return--
> <ipython-input-8-b234c8e7930d>(1)<module>()->None
-> import pdb; pdb.set_trace()
(Pdb) c
             Brandt   2014y   2013y   1413y  2014m  2013m  1413m      Datem
0              Lada  128633  151527    -15%  37030  44100   -16%  30-4-2014
1          Renault*   63647   67208     -5%  17395  19178    -9%  30-4-2014
2               KIA   60033   60027      0%  17744  18303    -3%  30-4-2014
3           Nissan*   57579   44188     30%  11835   8272    43%  30-4-2014
4          Hyundai*   57240   56582      1%  15933  15868     0%  30-4-2014
5           Toyota*   50160   44610     12%  15103  15278    -1%  30-4-2014
6         Chevrolet   48586   52489     -7%  13279  16083   -17%  30-4-2014
7                VW   45828   49477     -7%  11497  14203   -19%  30-4-2014
8        Mitsubishi   27943   26322      6%   6101   7182   -15%  30-4-2014
9             Škoda   26616   26107      2%   7724   7488     3%  30-4-2014
10             Opel   24493   26731     -8%   6493   6899    -6%  30-4-2014
11            Ford*   22760   32289    -30%   5387   8635   -38%  30-4-2014
12         GAZ LCV*   20318   24166    -16%   6274   7183   -13%  30-4-2014
13           Daewoo   17369   20139    -14%   4511   4241     6%  30-4-2014
14            Mazda   15818   12831     23%   4208   2206    91%  30-4-2014
15    Mercedes-Benz   14821   12165     22%   4437   3570    24%  30-4-2014
16              BMW   12836   12063      6%   3136   3245    -3%  30-4-2014
17             UAZ*   12539   15931    -21%   4073   4580   -11%  30-4-2014
18             Audi   11946   11929      0%   3660   3651     0%  30-4-2014
19         Peugeot*    8792   11607    -24%   2015   3300   -39%  30-4-2014
20            Honda    8760    7697     14%   1971   2749   -28%  30-4-2014
21         Citroёn*    8164    8619     -5%   1925   2672   -28%  30-4-2014
22        SsangYong    7739    9409    -18%   2006   2306   -13%  30-4-2014
23           Suzuki    7113    8954    -21%   1983   2921   -32%  30-4-2014
24            Lifan    6783    6437      5%   2178   2116     3%  30-4-2014
25       Land Rover    6769    6141     10%   1866   1641    14%  30-4-2014
26            Chery    6752    6269      8%   1801   2112   -15%  30-4-2014
27            Geely    6598    6573      0%   1747   2312   -24%  30-4-2014
28       Great Wall    5595    6928    -19%   1735   2243   -23%  30-4-2014
29           Subaru    5495    5897     -7%   1772   1888    -6%  30-4-2014
..              ...     ...     ...     ...    ...    ...    ...        ...
535            Jeep     678     598     13%   5768   3438    68%  30-9-2014
536        Infiniti     639     768    -17%   5921   6443    -8%  30-9-2014
537    Datsun******     520     NaN     NaN    520    NaN    NaN  30-9-2014
538         Porsche     232     294    -21%   3079   2726    13%  30-9-2014
539          Jaguar     138     157    -12%   1246   1247     0%  30-9-2014
540         Changan     120     NaN     NaN    785    NaN    NaN  30-9-2014
541           Haima     113      50    126%    606    237   156%  30-9-2014
542  Brilliance****     107     NaN     NaN    385    NaN    NaN  30-9-2014
543            MINI     104     240    -57%   1168   2053   -43%  30-9-2014
544            SEAT     101     276    -63%   1246   2939   -58%  30-9-2014
545        Cadillac     101     101      0%    949   1124   -16%  30-9-2014
546          Isuzu*      88      33    167%    396    131   202%  30-9-2014
547            BAW*      85     118    -28%    873   1266   -31%  30-9-2014
548        JAC*****      64     NaN     NaN    298    NaN    NaN  30-9-2014
549         Acura**      64     NaN     NaN    551    NaN    NaN  30-9-2014
550           smart      42      28     50%    260    146    78%  30-9-2014
551          TagAZ*      15      28    -46%    125    339   -63%  30-9-2014
552      Alfa Romeo       9     NaN     NaN     63    NaN    NaN  30-9-2014
553        Chrysler       5       8    -38%     91    141   -35%  30-9-2014
554          Luxgen       2     NaN     NaN     81    NaN    NaN  30-9-2014
555          Vortex       0       5     NaN      0    928    NaN  30-9-2014
556          Foton*       0       0      0%     59      6   883%  30-9-2014
557             ZAZ       0     102     NaN    481   2366   -80%  30-9-2014
558             BYD       0       0      0%      5    102   -95%  30-9-2014
559          Bogdan     NaN     125     NaN     92   1803   -95%  30-9-2014
560    Dodge*******     NaN      13     NaN     26    174   -85%  30-9-2014
561             Izh       0      37     NaN     19    647   -97%  30-9-2014
562             FAW     NaN     330     NaN   2164   3226   -33%  30-9-2014
563            cars    4336    4264    1.7%  36433  32043  13.7%  30-9-2014
564            vans    1028     480  114.2%   5617   3422  64.1%  30-9-2014

[565 rows x 8 columns]
In [5]:
pdtemp[0:3]
Out[5]:
Brandt 2014y 2013y 1413y 2014m 2013m 1413m Datem
0 Lada 36,513 40,011 -9% 283,802 343,368 -17% NaN
1 Renault* 15,406 17,254 -11% 139,434 155,081 -10% NaN
2 Hyundai* 15,398 17,171 -10% 132,849 135,609 -2% NaN
In [11]:
pdtemp[-1:]
Out[11]:
Brandt 2014y 2013y 1413y 2014m 2013m 1413m Datem
64 vans 1,028 480 114.2% 5,617 3,422 64.1% NaN

Не разобрался, как задать печать последних нескольких строк, поскольку

In [18]:
pdtemp[-1:-3], '....', pdtemp[-5:-1]
Out[18]:
(Empty DataFrame
 Columns: [Brandt, 2014y, 2013y, 1413y, 2014m, 2013m, 1413m, Datem]
 Index: [],
 '....',
           Brandt  2014y  2013y 1413y   2014m   2013m  1413m  Datem
 60  Dodge*******      -     13     -      26     174   -85%    NaN
 61           Izh      0     37     -      19     647   -97%    NaN
 62           FAW    n/a    330     -   2,164   3,226   -33%    NaN
 63          cars  4,336  4,264  1.7%  36,433  32,043  13.7%    NaN)

В лучшем случае глотает последнюю строчку, поэтому проще использовать

In [14]:
pdtemp.tail(3)
Out[14]:
Brandt 2014y 2013y 1413y 2014m 2013m 1413m Datem
62 FAW n/a 330 - 2,164 3,226 -33% NaN
63 cars 4,336 4,264 1.7% 36,433 32,043 13.7% NaN
64 vans 1,028 480 114.2% 5,617 3,422 64.1% NaN
In [ ]:
 
In [12]:
pdttemp.info(verbose=True, buf=None, max_cols=None, memory_usage=True, null_counts=True)
<class 'pandas.core.frame.DataFrame'>
Int64Index: 65 entries, 0 to 64
Data columns (total 8 columns):
Brandt    65 non-null object
2014y     62 non-null float64
2013y     58 non-null float64
1413y     52 non-null object
2014m     65 non-null int64
2013m     58 non-null float64
1413m     57 non-null object
Datem     65 non-null object
dtypes: float64(3), int64(1), object(4)
memory usage: 3.6+ KB
In [ ]:
#pd.Datem(pd001.dat)  # ==   pd.to_datetime(pd001['dat'])
In [14]:
pd.to_datetime(pdall.Datem).tail()  # ==   pd.to_datetime(pd001['Datem'])
Out[14]:
560   2014-09-30
561   2014-09-30
562   2014-09-30
563   2014-09-30
564   2014-09-30
Name: Datem, dtype: datetime64[ns]

Проверили? Теперь можно переприсвоить:

In [15]:
pdall.Datem = pd.to_datetime(pdall.Datem)

У нас осталось две строки процентов, надо убрать из них знаки "%" и перевести в формат float [

ИЗ Python for Data Analysis](http://pythonr.blogspot.ru/2015/03/blog-post.html#%D0%98%D0%97-Python-for-Data-Analysis)

Часть данных имеет вид целых, а в части есть 888.555 точка. В процессе предыдущих экспериментов я пытался все перевести в формат Int, но только посмотрев (распечатав выше) все данные, понял, почему выскакивала ошибка.

In [22]:
pdall['1413y'].str.replace('%','').astype(float)
Out[22]:
0    -15
1     -5
2      0
3     30
4      1
5     12
6     -7
7     -7
8      6
9      2
10    -8
11   -30
12   -16
13   -14
14    23
...
550     50.0
551    -46.0
552      NaN
553    -38.0
554      NaN
555      NaN
556      0.0
557      NaN
558      0.0
559      NaN
560      NaN
561      NaN
562      NaN
563      1.7
564    114.2
Name: 1413y, Length: 565, dtype: float64

Теперь проверим второй столбец (такой же)

In [23]:
pdall['1413m'].str.replace('%','').astype(float)
Out[23]:
0    -16
1     -9
2     -3
3     43
4      0
5     -1
6    -17
7    -19
8    -15
9      3
10    -6
11   -38
12   -13
13     6
14    91
...
550     78.0
551    -63.0
552      NaN
553    -35.0
554      NaN
555      NaN
556    883.0
557    -80.0
558    -95.0
559    -95.0
560    -85.0
561    -97.0
562    -33.0
563     13.7
564     64.1
Name: 1413m, Length: 565, dtype: float64

Проверили, все выглядит правдоподобно... Потому переприсвоим столбцы

In [24]:
pdall['1413y'] = pdall['1413y'].str.replace('%','').astype(float)
pdall['1413m'] = pdall['1413m'].str.replace('%','').astype(float)

Осталось проверить trailing spaces, но Pandas за такимим мелочами следит сам (в чем я не уверен)

Потму здесь просто распечатаеам итог

In [28]:
pdall.head(), pdall[30:40], pdall.tail(5)
Out[28]:
(     Brandt   2014y   2013y  1413y  2014m  2013m  1413m      Datem
 0      Lada  128633  151527    -15  37030  44100    -16 2014-04-30
 1  Renault*   63647   67208     -5  17395  19178     -9 2014-04-30
 2       KIA   60033   60027      0  17744  18303     -3 2014-04-30
 3   Nissan*   57579   44188     30  11835   8272     43 2014-04-30
 4  Hyundai*   57240   56582      1  15933  15868      0 2014-04-30,
                 Brandt  2014y  2013y  1413y  2014m  2013m  1413m      Datem
 30               Lexus   5475   4938     11   2100   1726     22 2014-04-30
 31               Volvo   4709   3974     18   1467   1066     38 2014-04-30
 32            VW vans*   4485   4917     -9   1204   1451    -17 2014-04-30
 33            Infiniti   3114   3246     -4    776    427     82 2014-04-30
 34                Jeep   2507   1198    109    650    353     84 2014-04-30
 35               FIAT*   2437   1890     29    682    646      6 2014-04-30
 36  Mercedes-Benz vans   2114   1201     76    604    366     65 2014-04-30
 37             Porsche   1191   1149      4    481    372     29 2014-04-30
 38                 FAW   1129   1028     10    342    522    -34 2014-04-30
 39              Jaguar    558    442     26    152    121     26 2014-04-30,
            Brandt  2014y  2013y  1413y  2014m  2013m  1413m      Datem
 560  Dodge*******    NaN     13    NaN     26    174  -85.0 2014-09-30
 561           Izh      0     37    NaN     19    647  -97.0 2014-09-30
 562           FAW    NaN    330    NaN   2164   3226  -33.0 2014-09-30
 563          cars   4336   4264    1.7  36433  32043   13.7 2014-09-30
 564          vans   1028    480  114.2   5617   3422   64.1 2014-09-30)
In [29]:
pdall.info(verbose=True, buf=None, max_cols=None, memory_usage=True, null_counts=True)
<class 'pandas.core.frame.DataFrame'>
Int64Index: 565 entries, 0 to 564
Data columns (total 8 columns):
Brandt    565 non-null object
2014y     550 non-null float64
2013y     510 non-null float64
1413y     461 non-null float64
2014m     564 non-null float64
2013m     510 non-null float64
1413m     503 non-null float64
Datem     565 non-null datetime64[ns]
dtypes: datetime64[ns](1), float64(6), object(1)
memory usage: 37.5+ KB

Осталось только сохранить объект Dateframe в файл

In [31]:
# Path to dir with files
#DIRPATH = '/media/MYLINUXLIVE/Documents/Xpdf/aerbu_2014_all_csv/1aug2/'
newpath = '/media/MYLINUXLIVE/Documents/Xpdf/aerbu_2014_all_csv_new'

#COLNAMES =['Brandt', '2014y', '2013y', '1413y', '2014m', '2013m', '1413m', 'Datem']
In [32]:
pdall.to_csv(newpath + '2014.csv', 
        sep=';', 
        #float_format='%.8f',
        cols=COLNAMES,
        index=False)
/usr/local/lib/python2.7/dist-packages/pandas/util/decorators.py:81: FutureWarning: the 'cols' keyword is deprecated, use 'columns' instead
  warnings.warn(msg, FutureWarning)

Надо бы записать информационный файл, пусть пока будет хоть какой-нибудь, а попозже надо бы его как-то структурировать

Зaписываем информационный файл

In [40]:
!mkdir /media/MYLINUXLIVE/Documents/Xpdf/aerbu_2014_all_csv_new
In [41]:
%%writefile /media/MYLINUXLIVE/Documents/Xpdf/aerbu_2014_all_csv_new/2014_info.txt
"""Записал первый вариант сводного файла за 2014 год из папки 
DIRPATH = '/media/MYLINUXLIVE/Documents/Xpdf/aerbu_2014_all_csv/1aug2/'

Здесь пока только 9 месяцев...
"""
Writing /media/MYLINUXLIVE/Documents/Xpdf/aerbu_2014_all_csv_new/2014_info.txt
In [ ]:
 


Посты чуть ниже также могут вас заинтересовать

Комментариев нет:

Отправить комментарий