Как изменить значение в серии панд в зависимости от условия - PullRequest
0 голосов
/ 21 ноября 2018

У меня есть ряд панд с только двоичными значениями

    0
0   1
1   0
2   0
3   0
4   1
5   0
6   1
7   0
8   0
9   1
10  0
11  1
12  0
13  1
14  0

Я хочу преобразовать значение в серию, где оно равно нулю и вокруг него есть одно, то есть, в основном, изменить 1, 0, 1 на 1, 1, 1.

Вывод, который мне нужен:

0     1
1     0
2     0
3     0
4     1
5     1
6     1
7     0
8     0
9     1
10    1
11    1
12    1
13    1
14    0

Я попытался создать скользящее окно из 3 и проверить, соответствуют ли значения мне.Есть ли лучший способ сделать это?

>>> window = df.rolling(3, center=True)
>>> (df[0] | window.apply(lambda x: 1 if (x == [1,0,1]).all() else 0)[0].fillna(0)).astype(int)

ПРИМЕЧАНИЕ: я тоже попробовал функцию сдвига.

Ответы [ 3 ]

0 голосов
/ 21 ноября 2018

Вы можете использовать rolling для выполнения центрированного движущегося окна длиной 3, а затем проверить, равно ли значение столбца 0 0 и в то же время, что sum изцентрированное движущееся окно с этим индексом равно 2, что означает, что окружающие отсчеты равны 1 с:

df['window'] = df.rolling(3, center = True).sum()
idx = df[(df.window == 2.0) & (df['0'] == 0)].index.values
df.loc[idx,'0'] = 1

print(df['0'])

0     1
1     0
2     0
3     0
4     1
5     1
6     1
7     0
8     0
9     1
10    1
11    1
12    1
13    1
14    0
0 голосов
/ 21 ноября 2018

Вы также можете использовать свертки для своего конкретного случая.

Вы можете использовать следующий фильтр:

[0.5, 0, 0.5]

То есть вы получаете местоположение только в том случае, если окружающие места принадлежат одному.,

Затем вы можете использовать это в качестве индекса, чтобы изменить значение ряда на 1.

from scipy.signal import convolve
print(df)
0     1
1     0
2     0
3     0
4     1
5     0
6     1
7     0
8     0
9     1
10    0
11    1
12    0
13    1
14    0
dtype: int64

df.iloc[convolve(df, [0.5, 0, 0.5], mode='same') == 1] = 1

print(df)

0     1
1     0
2     0
3     0
4     1
5     1
6     1
7     0
8     0
9     1
10    1
11    1
12    1
13    1
14    0

Выполнена небольшая проверка времени:

def check_convolve(df):
    df.iloc[convolve(df, [0.5, 0, 0.5], mode='same') == 1] = 1

def check_shifts(df):
     m1 = df.shift() == 1
     m2 = df.shift(-1) == 1
     m3 = df == 0
     df = np.where(m1 & m2 & m3, 1, df[0])


%timeit check_convolve(df)
205 µs ± 22.5 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit check_shifts(df)
1.16 ms ± 37.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
0 голосов
/ 21 ноября 2018

Используйте shift для логических масок и установите 1 на numpy.where:

m1 = df[0].shift() == 1
m2 = df[0].shift(-1) == 1
m3 = df[0] == 0

df[0] = np.where(m1 & m2 & m3, 1, df[0])

print (df)
    0
0   1
1   0
2   0
3   0
4   1
5   1
6   1
7   0
8   0
9   1
10  1
11  1
12  1
13  1
14  0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...