![](/img/trans.png)
[英]Pandas replace values if value isin dictionary of key and values as list
[英]Replace selected integer value with list of values with Pandas
我有一個pandas數據框,其中包含“Survived”列。
該列有兩個可能的值:1和0。
我想用[1,0]和0替換為[0,1]。
這些是我嘗試過的方法:
首先將列數據類型從int轉換為object:
data["Survived"] = data["Survived"].astype(object)
然后嘗試更改值(它們都可以使用整數,但不能使用列表):
data["Survived"][data["Survived"] == 1] = 5 # works
data["Survived"][data["Survived"] == 1] = [1, 0] # ValueError: cannot assign mismatch length to masked array
data["Survived"][::].replace(1, 5) # works
data["Survived"][::].replace(1, [1, 0]) # {TypeError}Invalid "to_replace" type: 'int'
以及導致這些錯誤的其他一些類似方法。
奇怪的是,我可以將值設置為逐個列出。
因此,如果我遍歷所有條目,我可以將它們全部更改為列表(這給出了我想要的結果):
for i, val in enumerate(data["Survived"]):
data["Survived"][i] = [1, 0] if val == 1 else [0, 1]
這怎么樣,既緩慢又難看。 大熊貓的做法是什么?
你可以使用numpy.where
與廣播:
data["Survived"] = np.where((data["Survived"] == 1)[:, None], [1,0],[0,1]).tolist()
如果您的數據框只包含0和1,則可以使用:
data.loc[:, 'Survived'] = data.Survived.apply(lambda x: [0,1] if x == 0 else [1,0])
檢查比較中的類型
編輯
IMO基於get_dummies
的答案不是最佳的,也不是使用np.where
因為你需要在你的級別導入numpy。
這里是使用apply
+ lambda
, np.where
和get_dummies
提出的解決方案所用時間的基准。
x軸是行數的log10(即7表示1e7行= 1000萬行)。
加起來:
對於較少數量的物品,幾乎沒有區別。
最好的(稍微)執行的解決方案是np.where
,但是你需要導入numpy
第二個最好的選擇是apply
非常接近第一個。
編輯2
按要求設置此處。
import pandas as pd
import numpy as np
import time
perfdf = pd.DataFrame(index=[3, 4, 5, 6, 7], columns=['apply', 'where', 'get_dummies'])
for s in perfdf.index:
data = pd.DataFrame({'Survived':np.random.randint(low=0,high=2, size=10**s)})
tstart = time.time()
pd.get_dummies(data.Survived).values[:, ::-1].tolist()
tstop = time.time()
perfdf.loc[s, 'get_dummies'] = tstop - tstart
tstart = time.time()
np.where((data["Survived"] == 1)[:, None], [1,0],[0,1]).tolist()
tstop = time.time()
perfdf.loc[s, 'where'] = tstop - tstart
tstart = time.time()
data.Survived.apply(lambda x: [0,1] if x == 0 else [1,0])
tstop = time.time()
perfdf.loc[s, 'apply'] = tstop - tstart
perfdf
選項1
使用get_dummies
df
Survived
0 1
1 0
2 1
3 0
4 0
5 1
6 1
7 0
df['Survived'] = pd.get_dummies(df.Survived).values[:, ::-1].tolist()
df
Survived
0 [1, 0]
1 [0, 1]
2 [1, 0]
3 [0, 1]
4 [0, 1]
5 [1, 0]
6 [1, 0]
7 [0, 1]
選項2
或者,使用numpy索引,假設您的列只有0和1。
i = np.array([[0, 1], [1, 0]])
df['Survived'] = i[df['Survived'].values].tolist()
df
Survived
0 [1, 0]
1 [0, 1]
2 [1, 0]
3 [0, 1]
4 [0, 1]
5 [1, 0]
6 [1, 0]
7 [0, 1]
計時
df = pd.concat([df] * 100000, ignore_index=True)
%timeit pd.get_dummies(df.Survived).values[:, ::-1].tolist()
1 loop, best of 3: 295 ms per loop
%timeit i[df['Survived'].values].tolist()
1 loop, best of 3: 273 ms per loop
%timeit np.where((df["Survived"] == 1)[:, None], [1,0],[0,1]).tolist()
1 loop, best of 3: 285 ms per loop
%timeit df.Survived.apply(lambda x: [0,1] if x == 0 else [1,0])
1 loop, best of 3: 368 ms per loop
所有這些解決方案同樣具有競爭力。 這是一個選擇問題,您決定使用哪一個。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.