Сдвиг столбцов DataFrame вверх на основе порогового значения, найденного в столбцах - PullRequest
4 голосов
/ 20 февраля 2020

У меня есть следующее df:

                           testcol_45    testcol_76    testcol_99
dates                                                   
2020021918                 -1.33           -1.29           -1.38   
2020022000                 -1.24           -1.33           -1.29   
2020022006               -999.00           -1.23           -1.33   
2020022012                 -0.88         -999.00           -1.21   
2020022018                 -0.70           -0.88         -999.00   
2020022100                 -0.46           -0.70           -0.89   
2020022106                 -0.37           -0.45           -0.70   

Я хотел бы сдвинуть столбцы вверх и не включать в них ячейки, содержащие значения -999, как только -999 достигнут для каждого столбца.

Мой желаемый результат будет выглядеть следующим образом:

                           testcol_45    testcol_76    testcol_99
dates                                                   
2020021918                 -0.88           -0.88           -0.89   
2020022000                 -0.70           -1.70           -0.70   
2020022006                 -0.46           -0.45              
2020022012                 -0.37                           
2020022018                                                    
2020022100                                                    
2020022106                                                   

(Длина столбца после выполнения этой операции в данном случае не имеет значения; кроме того, имена столбцов могут быть названы как угодно Я не могу ссылаться на них по имени).

Я пробовал различные итерации df.ffill и df.bfill, но безрезультатно.

Спасибо, что уделили время.

Ответы [ 4 ]

0 голосов
/ 20 февраля 2020

Давайте выясним индексы, где -999.0, затем переберем столбцы и сдвинем каждый из них снизу.

# resetting the index for flattening the dataframe
df.reset_index(inplace=True)

for col in df.columns:
    try:
        # finding the index where -990 occurs
        n_shift = df.index[df[col] == -999.0].tolist()[0] + 1

        # shifting the column from bottom
        df[col] = df[col].shift(-n_shift)

        print(f"Shifted : {col}")
    except IndexError:
        print(f"Not shifted : {col}")

# setting the index back to original
df.set_index(["dates"], inplace=True)

Это распечатает:

Not shifted : dates
Not shifted : testcol_45
Not shifted : testcol_76
Not shifted : testcol_99

Фрейм данных выглядит следующим образом:

            testcol_45  testcol_76  testcol_99
dates                                         
2020021918       -0.88       -0.88       -0.89
2020022000       -0.70       -0.70       -0.70
2020022006       -0.46       -0.45         NaN
2020022012       -0.37         NaN         NaN
2020022018         NaN         NaN         NaN
2020022100         NaN         NaN         NaN
2020022106         NaN         NaN         NaN
0 голосов
/ 20 февраля 2020

Это хороший вопрос, и вы, безусловно, можете сделать это, используя shift() метод pandas dataframe,

Примечание:

pandas.DataFrame.shift(periods=?)

Сдвиг индекса на желаемое количество периодов

df.reset_index(inplace=True)

for col in df.columns:
    if col.startswith("testcol"):
        idx = df.index[df[col] == -999].tolist()[0]
        df[col] = df[col].loc[idx + 1:]
        df[col] = df[col].shift(periods=-(idx + 1))

df.set_index(["dates"], inplace=True)

И результат будет

            testcol_45  testcol_76  testcol_99
dates                                         
2020021918       -0.88       -0.88       -0.89
2020022000       -0.70       -0.70       -0.70
2020022006       -0.46       -0.45         NaN
2020022012       -0.37         NaN         NaN
2020022018         NaN         NaN         NaN
2020022100         NaN         NaN         NaN
2020022106         NaN         NaN         NaN

Надеюсь, он вам поможет!

0 голосов
/ 20 февраля 2020

Вы можете найти индекс строки с -999 и сместить значения столбца.

(
    df.reset_index()
    .apply(lambda x: x.shift(-x.eq(-999).idxmax()-1) if x.eq(-999).any() else x)
    .set_index('dates')
)


            testcol_45  testcol_76  testcol_99
dates           
2020021918  -0.88       -0.88       -0.89
2020022000  -0.70       -0.70       -0.70
2020022006  -0.46       -0.45       NaN
2020022012  -0.37       NaN         NaN
2020022018  NaN         NaN         NaN
2020022100  NaN         NaN         NaN
2020022106  NaN         NaN         NaN
0 голосов
/ 20 февраля 2020

Вы можете замаскировать вершину с помощью nan и использовать идеи из этого вопроса для смещения данных. Например, вы можете маскировать с помощью:

df.where(df.eq(-999)[::-1].cumsum().eq(0))

Вывод:

            testcol_45  testcol_76  testcol_99
dates                                         
2020021918         NaN         NaN         NaN
2020022000         NaN         NaN         NaN
2020022006         NaN         NaN         NaN
2020022012       -0.88         NaN         NaN
2020022018       -0.70       -0.88         NaN
2020022100       -0.46       -0.70       -0.89
2020022106       -0.37       -0.45       -0.70
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...