2017-02-05 2 views
2

Я пытаюсь создать панда dataframe вроде этого:Панда: создать новый столбец меняющего значение других строк

  x2  x3 
0 3.536220 0.681269 
1 0.681269 3.536220 
2 -0.402380 2.303833 
3 2.303833 -0.402380 
4 2.032329 3.334412 
5 3.334412 2.032329 
6 0.371338 5.879732 
. . . 

Так x2 представляет собой столбец случайных чисел, и х3 имеет значение строки 0 и 1 в x2 заменены, значения 2 и 3 меняются местами и так далее. Мой текущий код выглядит так:

import numpy as np 
import pandas as pd 
x2 = pd.Series(np.random.normal(loc = 2, scale = 2.5, size = 1000)) 
x3 = pd.Series([x2[i + 1] if i % 2 == 0 else x2[i - 1] for i in range(1000)]) 
df = pd.DataFrame({'x2': x2, 'x3': x3}) 

мне интересно, если есть какой-либо быстрее или более элегантный способ, особенно если я хочу иметь много строк (например, 1 млн евро) или делать это снова и снова (например, моделирование методом Монте-Карло)?

ответ

6

Вместо

[x2[i + 1] if i % 2 == 0 else x2[i - 1] for i in range(1000)] 

можно использовать

def swap(arr): 
    result = np.empty_like(arr) 
    result[::2] = arr[1::2] 
    result[1::2] = arr[::2] 
    return result 

Для последовательности длины 1000, с использованием swap закончилась 3000X быстрее:

In [84]: %timeit [x2[i + 1] if i % 2 == 0 else x2[i - 1] for i in range(1000)] 
100 loops, best of 3: 12.7 ms per loop 

In [98]: %timeit swap(x2.values) 
100000 loops, best of 3: 3.82 µs per loop 

import numpy as np 
import pandas as pd 
np.random.seed(2017) 
x2 = pd.Series(np.random.normal(loc = 2, scale = 2.5, size = 1000)) 
x3 = [x2[i + 1] if i % 2 == 0 else x2[i - 1] for i in range(1000)] 

def swap(arr): 
    result = np.empty_like(arr) 
    result[::2] = arr[1::2] 
    result[1::2] = arr[::2] 
    return result 

df = pd.DataFrame({'x2': x2, 'x3': x3, 'x4': swap(x2.values)}) 
print(df.head()) 

печатает

  x2  x3  x4 
0 -0.557363 1.649005 1.649005 
1 1.649005 -0.557363 -0.557363 
2 2.497731 3.433690 3.433690 
3 3.433690 2.497731 2.497731 
4 1.013555 0.679394 0.679394 
Смежные вопросы