簡體   English   中英

將所選的整數值替換為帶有Pandas的值列表

[英]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 + lambdanp.whereget_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM