Сумма количества, где значения меньше строки

#python #pandas

#python #pandas

Вопрос:

Я использую Pandas для создания нового столбца, который будет выполнять поиск по всему столбцу со значениями [1-100] и будет считать значения, где они меньше текущей строки.

Смотрите пример [df] ниже:

 [A][NewCol]
 1 0
 3 2
 2 1
 5 4
 8 5
 3 2
  

По сути, для каждой строки мне нужно просмотреть весь столбец A и подсчитать, на сколько значений меньше текущей строки. Итак, для значения 5 существует 4 значения, которые меньше (<), чем 5 (1,2,3,3).

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

Спасибо!

Комментарии:

1. похоже, то, что вы ищете, — это ваша пользовательская версия rank (A) — checkout pandas.pydata.org/pandasdocs/stable/reference/api / … чтобы посмотреть, сможете ли вы достичь результата с помощью функции rank, поскольку это было бы самой чистой реализацией здесь

Ответ №1:

Один из способов сделать это подобным образом, использовать rank с method='min' :

 df['NewCol'] = (df['A'].rank(method='min') - 1).astype(int)
  

Вывод:

    A  NewCol
0  1       0
1  3       2
2  2       1
3  5       4
4  8       5
5  3       2
  

Комментарии:

1. Я думаю, что выходные данные нужно немного скорректировать.

2. @Wen-Ben Спасибо.

3. @Wen-Ben LOL Я знал, что это можно сделать с помощью rank. Мне пришлось перебирать все методы ранжирования. 🙂

4. Теперь выглядит лучше 🙂

5. Спасибо! Изначально я думал использовать rank, но я не знаю, что вы могли бы использовать метод min и вычесть 1. Гениально!

Ответ №2:

Я использую numpy широковещательную

 s=df.A.values
(s[:,None]>s).sum(1)
Out[649]: array([0, 2, 1, 4, 5, 2])

#df['NewCol']=(s[:,None]>s).sum(1)
  

время

 df=pd.concat([df]*1000)

%%timeit
s=df.A.values
(s[:,None]>s).sum(1)
10 loops, best of 3: 83.7 ms per loop
%timeit (df['A'].rank(method='min') - 1).astype(int)
1000 loops, best of 3: 479 µs per loop
  

Комментарии:

1. Возможно ли добавить тайминги? Я думаю, что rank должен быть быстрее, но не уверен на 100% в больших данных.

2. @jezrael Я чувствую то же самое 🙂

3. Возможно ли добавить тайминги?

4. Спасибо, только не уверен, какие данные повторно использовались для timeit?

5. @jezrael добавил 🙂

Ответ №3:

Попробуйте этот код

 A = [Your numbers]
less_than = []
    for element in A:
        counter = 0
        for number in A:
            if number < element:
                counter  = 1
        less_than.append(counter)
  

Ответ №4:

Вы можете сделать это таким образом:

 import pandas as pd

df = pd.DataFrame({'A': [1,3,2,5,8,3]})

df['NewCol'] = 0
for idx, row in df.iterrows():
    df.loc[idx, 'NewCol'] = (df.loc[:, 'A'] < row.A).sum()

print(df)
  
    A  NewCol
0  1       0
1  3       2
2  2       1
3  5       4
4  8       5
5  3       2
  

Ответ №5:

Другой способ — сортировать и сбрасывать индекс:

 m=df.A.sort_values().reset_index(drop=True).reset_index()
m.columns=['new','A']
print(m)

   new  A
0    0  1
1    1  2
2    2  3
3    3  3
4    4  5
5    5  8
  

Ответ №6:

Вы не указали, важна ли скорость или использование памяти (или у вас очень большой набор данных). «Самый простой» способ сделать это прямолинейно: вычислите, сколько меньше i для каждой записи в столбце, и соберите их в новый столбец:

 df=pd.DataFrame({'A': [1,3,2,5,8,3]})
col=df['A']
df['new_col']=[ sum(col<i) for i in col ]

print(df)
  

Результат:

    A  new_col
0  1        0
1  3        2
2  2        1
3  5        4
4  8        5
5  3        2
  

Могут быть более эффективные способы сделать это на больших наборах данных, например, сначала отсортировать ваш столбец.