2016-04-19 5 views
3

Я пишу программу в Python, чтобы заменить некоторые значения кадра данных, идея заключается в том, что у меня есть файл с именем file.txt и выглядит следующим образом:Как оптимизировать следующий код?

A:s:Y:0.1:0.1:0.1:0.2:0.1 
B:r:D:0.3:0.5:0.1:0.2:0.2 
C:f:C:0.3:0.4:0.2:-0.1:0.4 
D:f:C:0.1:0.2:0.1:0.1:0.1 
F:f:C:0.1:-0.1:-0.1:0.1:0.1 
G:f:C:0.0:-0.1:0.1:0.3:0.4 
H:M:D:0.1:0.4:0.1:0.0:0.4 

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

всех значений, которые принадлежат х до range1 будут заменена на «N»:

range1=[-0.2,-0.1,0,0.1,0.2] -> 'N' 

Все значения, принадлежащие к диапазону 2, являются будет заменен на «L»:

range2=[-0.5,-0.4,-0.3] -> 'L' 

Все значения, которые принадлежат к диапазон 3 будут заменены на «H»:

range3=[0.3,0.4,0.5] 

Для того, чтобы достичь этого я попытался следующие :

import pandas as pd 

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

labels=df[3] 


range1=[-0.2,-0.1,0,0.1,0.2] 

range2=[-0.5,-0.4,-0.3] 

range3=[0.3,0.4,0.5] 

lookup = {'N': range1, 'L': range2, 'H': range3} 




for k, v in lookup.items(): 
    df.loc[df[3].isin(v), 3] = k 


for k, v in lookup.items(): 
    df.loc[df[4].isin(v), 4] = k 


for k, v in lookup.items(): 
    df.loc[df[5].isin(v), 5] = k 

for k, v in lookup.items(): 
    df.loc[df[6].isin(v), 6] = k 

for k, v in lookup.items(): 
    df.loc[df[7].isin(v), 7] = k 


print(df) 

И это работает хорошо, но я хочу, чтобы избежать использования многого ФОРСА, я хотел бы, чтобы оценить любые предложения о том, как достичь этого.

ответ

4

Вы можете использовать where вместо:

for k, v in lookup.items(): 
    df = df.where(~df.isin(v), k) 

Это говорит о том, чтобы сохранить значения df, когда эти значения не содержатся в v. В противном случае замените их на значение k. Назначение перезаписывает df на каждой итерации для накопления категориальных меток.

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

Существует еще один вариант для where, который определяет модификацию на месте, но, к сожалению, он не может использоваться с DataFrames со смешанными типами столбцов. В вашем примере столбцы 0, 1 и 2 имеют тип object, а остальные - тип float. Таким образом, pandas консервативно (и неэффективно) предполагает, что он должен был бы преобразовать все в object, чтобы выполнить замену на месте, и повышает значение TypeError, а не проверяет, действительно ли затронуты только те же типизированные столбцы.

Например, это:

df.where(~df.isin(v), k, inplace=True) 

поднимет TypeError.

Это ограничение с Pandas довольно расстраивает.Например, вы не можете использовать регулярное назначение панд работать вокруг него или, как следующий также дает тот же TypeError:

for k, v in lookup.items(): 
    df.where(~df.isin(v), inplace=True) 
    df[df.isnull()] = k # <-- same TypeError 

и удивительно установив аргумент try_cast ключевое слово, чтобы True и/или установить аргумент raise_on_error ключевых слов False не влияют на поднятие TypeError, поэтому вы не можете отключить эту проверку безопасности при использовании where.

+0

Спасибо за поддержку, да, в моем кадре данных есть смешанные типы столбцов, но первый подход, который вы мне дали, был очень полезным, вот что я искал. – neo33

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