2015-10-29 2 views
3

Я пытаюсь сделать некоторые простые анализы в отраслевых портфелях Kenneth French (впервые с Pandas/Python), данные в формате txt (см. Ссылку в коде). Прежде, чем я могу сделать вычисления, сначала хочу, чтобы загрузить его в dataframe панды правильно, но я боролся с этим в течение нескольких часов:Pandas dataframe конвертирует определенные столбцы из строки в float

import urllib.request 
import os.path 
import zipfile 
import pandas as pd 
import numpy as np 

# paths 
url = 'http://mba.tuck.dartmouth.edu/pages/faculty/ken.french/ftp/48_Industry_Portfolios_CSV.zip' 
csv_name = '48_Industry_Portfolios.CSV' 
local_zipfile = '{0}/data.zip'.format(os.getcwd()) 
local_file = '{0}/{1}'.format(os.getcwd(), csv_name) 

# download data 
if not os.path.isfile(local_file): 
    print('Downloading and unzipping file!') 
    urllib.request.urlretrieve(url, local_zipfile) 
    zipfile.ZipFile(local_zipfile).extract(csv_name, os.path.dirname(local_file)) 

# read from file 
df = pd.read_csv(local_file,skiprows=11) 
df.rename(columns={'Unnamed: 0' : 'dates'}, inplace=True) 

# build new dataframe 
first_stop = df['dates'][df['dates']=='201412'].index[0] 
df2 = df[:first_stop] 

# convert date to datetime object 
pd.to_datetime(df2['dates'], format = '%Y%m') 
df2.index = df2.dates 

Все столбцы, кроме дат, представляют собой финансовые доходы. Однако из-за форматирования файлов они теперь являются строками. Согласно документам Pandas, это должно сделать трюк:

df2.convert_objects(convert_numeric=True) 

Но столбцы остаются строками. Другие предложения должны цикл по столбцам (смотрите, например, pandas convert strings to float for multiple columns in dataframe):

for d in df2.columns: 
if d is not 'dates': 
    df2[d] = df2[d].map(lambda x: float(x)/100) 

Но это дает мне следующее предупреждение:

home/<xxxx>/Downloads/pycharm-community-4.5/helpers/pydev/pydevconsole.py:3: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame. 
Try using .loc[row_indexer,col_indexer] = value instead 

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy 
    try: 

Я прочитал документацию на представлениях против копий, но испытывают трудности чтобы понять, почему это проблема в моем случае, но не в фрагментах кода в вопросе, с которым я связан. Благодаря

Edit:

df2=df2.convert_objects(convert_numeric=True) 

ли трюк, хотя я получил предупреждение амортизации (как ни странно, что не в документации на http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.convert_objects.html)

Некоторые из df2:

 dates Agric Food  Soda  Beer  Smoke Toys  Fun \ 
dates                   
192607 192607  2.37  0.12 -99.99 -5.19  1.29  8.65  2.50 
192608 192608  2.23  2.68 -99.99 27.03  6.50 16.81 -0.76 
192609 192609 -0.57  1.58 -99.99  4.02  1.26  8.33  6.42 
192610 192610 -0.46 -3.68 -99.99 -3.31  1.06 -1.40 -5.09 
192611 192611  6.75  6.26 -99.99  7.29  4.55  0.00  1.82 

Edit2: решение на самом деле проще, чем я думал:

df2.index = pd.to_datetime(df2['dates'], format = '%Y%m') 
df2 = df2.astype(float)/100 
+0

глупо Вопрос: вы назначили результат «convert_objects»? например'df = df.convert_objects (convert_numeric = True)'? – EdChum

+0

Можете вы добавить что-то вроде 'df2'? Измените свой вопрос, по крайней мере, с частичным представлением фрейма данных. – bourbaki4481472

+0

@EdChum: это работает, хотя я не понимаю, зачем мне нужно назначать результат, разве это не хранится? Также сохраняются переименованные столбцы. – zundertj

ответ

0

Вы должны присвоить результат convert_objects, как нет inplace пар:

df2=df2.convert_objects(convert_numeric=True) 

вы обратитесь к rename но у этого есть параметр inplace, который вы установили на True.

Большинство операций в пандах возвращают копию, а некоторые имеют inplace param, convert_objects - это тот, который этого не делает. Вероятно, это связано с тем, что если преобразование завершается неудачно, вы не хотите использовать данные с NaNs.

Также предупреждение об отказе состоит в том, чтобы разделить различные процедуры преобразования, предположительно, чтобы вы могли специализировать параметры, например. Формат строки для даты и времени и т.д ..

+0

Спасибо за помощь! Я добавил решение, просто понял, что у меня была такая же проблема с преобразованием дат. Может быть, немного не по теме, но предположим, что я хотел бы только преобразовать один столбец из строк в float (как я пытался сделать в своем исходном вопросе), как я могу избежать настройкиWithCopyWarning? – zundertj

+0

Вы должны отфильтровать df для объектов dtypes, а затем использовать их с помощью 'astype', что-то вроде' cols = list (df) cols.pop ('date' для col in cols: df [cols] = df [cols]. astype (float)/100' должен работать, но действительно 'convert_objects' - это способ пойти – EdChum

0

Я хотел бы попробовать следующее, чтобы заставить конвертировать все в поплавки:

df2=df2.astype(float) 
0

Вы можете конвертировать конкретный столбец плавать (или любого числового типа по этому вопросу) по

df["column_name"] = pd.to_numeric(df["column_name"]) 

отправляю это, потому что pandas.convert_objects осуждается в панд 0.20.1

Смежные вопросы