[英]how to optimize the following code?
我在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'
屬於range2的所有值將替換為'L':
range2=[-0.5,-0.4,-0.3] -> 'L'
屬於range3的所有值將被替換為'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)
它運作良好,但我想避免使用這么多的fors,我想欣賞任何有關如何實現這一點的建議。
您可以where
使用:
for k, v in lookup.items():
df = df.where(~df.isin(v), k)
這表示當v
中不包含這些值時保留df
的值。 否則,用值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
時無法禁用此類型安全檢查。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.