У меня есть такой фрейм данных
Name Year Value
0 Mexico 1961 14357
1 Mexico 1961 15161
2 Mexico 1961 514658
3 Mexico 1962 15559
4 United States of America 1977 2191197
5 United States of America 1978 2470734
6 United States of America 1978 52470734
7 United States of America 1979 2737377
8 United States of America 1979 52731457
9 United States of America 1980 3029030
10 United States of America 1980 53024589
11 United States of America 1981 3272565
12 United States of America 2010 15199150
13 United States of America 2010 515543018
14 United States of America 2011 15861873
15 United States of America 2011 16250364
Я хочу преобразовать его в:
Name Year Value
0 Mexico 1961 14357
1 Mexico 1961 15161
2 Mexico 1961 14658
3 Mexico 1962 15559
4 United States of America 1977 2191197
5 United States of America 1978 2470734
6 United States of America 1978 2470734
7 United States of America 1979 2737377
8 United States of America 1979 2731457
9 United States of America 1980 3029030
10 United States of America 1980 3024589
11 United States of America 1981 3272565
12 United States of America 2010 15199150
13 United States of America 2010 15543018
14 United States of America 2011 15861873
15 United States of America 2011 16250364
Как вы можете видеть, когда последний столбец был значительно больше, чем его соседи, он был заменен другим числом, которое представляет собой просто удаление 5 из его начала.
например, для Мексики в 3-й строке 514658
заменяется на 14658
, во-первых, потому что 514658 значительно (5x-10x) больше, чем его соседи, то есть 15161
и 15559
.
Аналогично для США,
United States of America,1979,52731457
заменяется на
United States of America,1979,2731457
Сходным образом
United States of America,1978,52470734
United States of America,1980,53024589
United States of America,2010,515543018
заменяются на
United States of America,1978,2470734
United States of America,1980,3024589
и
United States of America,2010,15543018
соответственно.
Но заметьте,
Name
, должен точно совпадать,Value
, должен начинаться с 5 иValue
должен быть значительно больше, т. е. в основном на одну цифру больше, чем у соседей, чтобы избежать риска удаления ложных срабатываний.Возможно, вы уже поняли, что это упражнение по очистке данных, в котором некоторые символы $
записаны как 5 и, следовательно, должны быть исправлены.
🤔 А знаете ли вы, что...
Python является интерпретируемым языком программирования.
Вероятно, вы захотите сравнить предыдущее или следующее значение, так как если вы сравниваете только со следующим, вы не сможете исправить ошибки, которые оказались последней записью для этой страны.
Поэтому создайте столбцы отставания и опережения, сгруппированные по странам, используя pandas.DataFrame.shift(), а затем создайте логическую маску значений для замены, где:
Конечно, если у вас есть страны только с одной записью, это не заменит никаких значений для этой страны.
df['lag'] = df.groupby('Name')['Value'].shift(1)
df['lead'] = df.groupby('Name')['Value'].shift(-1)
replace_val = (
df['Value'].astype(str).str.startswith('5') &
(
(df['Value'] > df['lag'] * 5) |
(df['Value'] > df['lead'] * 5)
)
)
df.loc[replace_val, 'Value'] = df.loc[replace_val, 'Value'].astype(str).str[1:].astype(int)
df.drop(["lag", "lead"], axis = 1, inplace=True)
Выход:
Name Year Value
0 Mexico 1961 14357
1 Mexico 1961 15161
2 Mexico 1961 14658
3 Mexico 1962 15559
4 United States of America 1977 2191197
5 United States of America 1978 2470734
6 United States of America 1978 2470734
7 United States of America 1979 2737377
8 United States of America 1979 2731457
9 United States of America 1980 3029030
10 United States of America 1980 3024589
11 United States of America 1981 3272565
12 United States of America 2010 15199150
13 United States of America 2010 15543018
14 United States of America 2011 15861873
15 United States of America 2011 16250364
data = {
"Name": [ "Mexico", "Mexico", "Mexico", "Mexico", "United States of America", "United States of America", "United States of America", "United States of America", "United States of America", "United States of America", "United States of America", "United States of America", "United States of America", "United States of America", "United States of America", "United States of America" ],
"Year": [ 1961, 1961, 1961, 1962, 1977, 1978, 1978, 1979, 1979, 1980, 1980, 1981, 2010, 2010, 2011, 2011 ],
"Value": [ 14357, 15161, 514658, 15559, 2191197, 2470734, 52470734, 2737377, 52731457, 3029030, 53024589, 3272565, 15199150, 515543018, 15861873, 16250364 ]
}
df = pd.DataFrame(data)