#python #pandas #dataframe
Вопрос:
У меня есть фрейм данных в этой форме:
Name Rank Months
A 'A3' 2
A 'A3' 2
A 'A2' 3
A 'A2' 3
A 'A2' 3
B 'A1' 4
B 'A1' 4
B 'A1' 4
B 'A1' 4
C 'A3' 2
C 'A3' 2
C 'A2' 1
Каков наиболее эффективный способ создания нового столбца с добавочными значениями на основе количества месяцев для определенного имени и при условии ранга?
Таким образом, в основном результат выглядит следующим образом:
Name Rank Months NewIncremental
A 'A3' 2 'P4'
A 'A3' 2 'P5'
A 'A2' 3 'P1'
A 'A2' 3 'P2'
A 'A2' 3 'P3'
B 'A1' 4 'P1'
B 'A1' 4 'P2'
B 'A1' 4 'P3'
B 'A1' 4 'P4'
C 'A3' 2 'P2'
C 'A3' 2 'P3'
C 'A2' 1 'P1'
Таким образом, условием будет порядок рангов, который равен A1->A2->>A3. Это означает, что если есть имя с рангом A2, я присваиваю меньшее добавочное значение. Я думаю, сортировка на основе этого может помочь?
ИЗМЕНИТЬ: отредактированный порядок, так что мне нужно указать произвольный порядок рангов
Ответ №1:
Один подход:
ranks = df.sort_values(by=["Rank"],
key=lambda x: x.str.replace(r"D ", "", regex=True).astype(int))
.groupby("Name").transform("cumcount") 1
ranks = ranks.apply("P{}".format)
df["NewIncremental"] = ranks
print(df)
Выход
Name Rank Months NewIncremental
0 A A1 2 P1
1 A A1 2 P2
2 A A2 3 P3
3 A A2 3 P4
4 A A2 3 P5
5 B A1 4 P1
6 B A1 4 P2
7 B A1 4 P3
8 B A1 4 P4
9 C A3 2 P2
10 C A3 2 P3
11 C A2 1 P1
Шаг за шагом
# sort df by the given criteria, then group-by
sorted_by_rank = df.sort_values(by=["Rank"], key=lambda x: x.str.replace(r"D ", "", regex=True).astype(int))
# get the ranks and apply the expected format
ranks = sorted_by_rank.groupby("Name").transform("cumcount") 1
ranks = ranks.apply("P{}".format)
# assign the new column
df["NewIncremental"] = ranks
print(df)
Ответ №2:
Решает ли это проблему для вас?
df['NewIncrement'] = 'P' df.sort_values(['Name', 'Rank']).groupby('Name').rank(method="first", ascending=True).astype(int).astype(str)
Ответ №3:
IIOC вы можете просто использовать rank
:
df["new"] = "P" df.groupby("Name")["Rank"].rank(method="first").astype(int).astype(str)
print (df)
Name Rank Months new
0 A 'A1' 2 P1
1 A 'A1' 2 P2
2 A 'A2' 3 P3
3 A 'A2' 3 P4
4 A 'A2' 3 P5
5 B 'A1' 4 P1
6 B 'A1' 4 P2
7 B 'A1' 4 P3
8 B 'A1' 4 P4
9 C 'A3' 2 P2
10 C 'A3' 2 P3
11 C 'A2' 1 P1
Комментарии:
1. Можно ли использовать какой-то пользовательский порядок рангов? Потому что, насколько я понимаю
first
, метод ранжируется на основе того, как эти значения отображаются в кадре данных. Если бы » А2 » появилось в первом ряду, это бы больше не работало?2.
first
ранги присваиваются в порядке их появления в массиве, которые имеют одинаковое значение после вычисления числовых рядов данных по оси, так что это будет работать просто отлично.