Присвойте столбцу значение, равное значению - pandas df - PullRequest
0 голосов
/ 22 февраля 2019

Я пытаюсь assign значения в pandas df.В частности, для df ниже я хочу использовать Column['On'], чтобы определить, сколько значений происходит в настоящее время.Затем я хочу назначить эти значения в группах 3.Значения;

1-3 = 1
4-6 = 2
7-9 = 3 etc

Это может доходить до 20-30 значений.Я рассмотрел np.where, но это не очень эффективно, и я возвращаю ошибку.

import pandas as pd
import numpy as np

d = ({                
    'On' : [1,2,3,4,5,6,7,7,6,5,4,3,2,1],                                     
      })

df = pd.DataFrame(data=d)

Этот вызов работает:

df['P'] = np.where(df['On'] == 1, df['On'],1)

Но если я хочу применить это к другим значениям, я получаю сообщение об ошибке:

df = df['P'] = np.where(df['On'] == 1, df['On'],1)
df = df['P'] = np.where(df['On'] == 2, df['On'],1)
df = df['P'] = np.where(df['On'] == 3, df['On'],1)

IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

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

import pandas as pd
import numpy as np
n = 1000 
df = pd.DataFrame({"On":np.random.randint(1,20, n)})

Решение AlexG

%%time
j = 1
df["P"] =  np.nan
for i in range(1, 20):
    df['P'].loc[(df['On'] >= j) & (df['On'] <= (j+2))] = i
    j += 3

CPU times: user 2.11 s, sys: 0 ns, total: 2.11 s
Wall time: 2.11 s

Предлагаемое решение

%%time
df["P"] = np.ceil(df["On"]/3)


CPU times: user 2.48 ms, sys: 0 ns, total: 2.48 ms
Wall time: 2.15 ms

Ускорение ~1000x

0 голосов
/ 22 февраля 2019

Вы можете использовать маски серий и loc

df['P'] = float('nan')
df['P'].loc[(df['On'] >= 1) & (df['On'] <= 3)] = 1
df['P'].loc[(df['On'] >= 4) & (df['On'] <= 6)] = 2
# ...etc

Это довольно просто расширить с помощью цикла

j = 1
for i in range(1, 20):
    df['P'].loc[(df['On'] >= j) & (df['On'] <= (j+2))] = i
    j += 3
...