Pandas DataFrame изменяет значение на основе сравнения столбцов и значений индекса - PullRequest
0 голосов
/ 02 ноября 2018

Предположим, что у вас есть панда DataFrame, которая содержит какие-то данные в теле и числа в именах column и index.

>>> data=np.array([['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']])
>>> columns = [2, 4, 8]
>>> index = [10, 4, 2]
>>> df = pd.DataFrame(data, columns=columns, index=index)
>>> df
    2  4  8
10  a  b  c
4   d  e  f
2   g  h  i

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

Если индекс больше столбца, заменить букву 'k':

    2  4  8
10  k  k  k
4   k  e  f
2   g  h  i

Если индекс равен столбцу, заменить букву на «U»:

    2  4  8
10  k  k  k
4   k  U  f
2   U  h  i

Если столбец больше индекса, заменить букву на «Y»:

    2  4  8
10  k  k  k
4   k  U  Y
2   U  Y  Y

Чтобы вопрос был полезен для всех:

  • Какой быстрый способ сделать эту замену?

  • Какой самый простой способ сделать эту замену?

Скорость Результаты из минимального примера

  • Jezrael : 556 µs ± 66.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

  • user3471881 : 329 µs ± 11.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

  • Гром : 4.65 ms ± 252 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)


Это дубликат? Я искал в Google для pandas replace compare index column и лучшие результаты:

Pandas - сравнивает два кадра данных и заменяет значения, соответствующие условию

Python pandas: заменить значения на основе местоположения, а не значения индекса

Pandas DataFrame: заменить все значения в столбце на основе условия

Тем не менее, я не чувствую никакого прикосновения к тому, возможно ли это a) или b) как сравнивать таким образом

Ответы [ 3 ]

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

Не уверен, что самый быстрый способ сделать это, но невероятно простой способ - просто перебрать кадр данных, например:

for i in df.index:
    for j in df.columns:
        if i>j:
            df.loc[i,j]='k'
        elif j>i:
            df.loc[i,j]='y'
        else:
            df.loc[i,j]='u'
0 голосов
/ 02 ноября 2018

1. Использование np.arrays + np.select:

values = np.array(np.array([df.index]).transpose() - np.array([df.columns]))

greater = values > 0
same = values == 0

df = pd.DataFrame(np.select([greater, same], ['k', 'U'], 'Y'), columns=df.columns, index=df.index)

2. Использование np.arrays и ручная маскировка.

values = np.array(np.array([df.index]).transpose() - np.array([df.columns]), dtype='object')

greater = values > 0
less = values < 0
same = values == 0

values[greater] = 'k'
values[less] = 'Y'
values[same] = 'U'


df = pd.DataFrame(values, columns=df.columns, index=df.index)
0 голосов
/ 02 ноября 2018

Я думаю, вам нужно numpy.select с трансляцией:

m1 = df.index.values[:, None] > df.columns.values
m2 = df.index.values[:, None] == df.columns.values


df = pd.DataFrame(np.select([m1, m2], ['k','U'], 'Y'), columns=df.columns, index=df.index)
print (df)
    2  4  8
10  k  k  k
4   k  U  Y
2   U  Y  Y

Performance

np.random.seed(1000)

N = 1000
a = np.random.randint(100, size=N)
b = np.random.randint(100, size=N)

df = pd.DataFrame(np.random.choice(list('abcdefgh'), size=(N, N)), columns=a, index=b)
#print (df)

def us(df):
    values = np.array(np.array([df.index]).transpose() - np.array([df.columns]), dtype='object')
    greater = values > 0
    less = values < 0
    same = values == 0

    values[greater] = 'k'
    values[less] = 'Y'
    values[same] = 'U'


    return pd.DataFrame(values, columns=df.columns, index=df.index)

def jez(df):

    m1 = df.index.values[:, None] > df.columns.values
    m2 = df.index.values[:, None] == df.columns.values
    return pd.DataFrame(np.select([m1, m2], ['k','U'], 'Y'), columns=df.columns, index=df.index)

In [236]: %timeit us(df)
107 ms ± 358 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [237]: %timeit jez(df)
64 ms ± 299 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...