簡體   English   中英

根據列的排序更改熊貓數據框中切片的值

[英]Change values from a slice in pandas dataframe depending on the sorting of a column

根據某些特定的排序,我在修改熊貓數據框中的值時遇到了一些麻煩。

我的 DataFrame 就像

df_test = pd.DataFrame({'month':[1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3],
                        'day':[1,1,1,2,2,2,1,1,1,2,2,2,1,1,1,2,2,2],
                       'period':[np.random.choice(['a','b']) for i in range(18)],
                        'to_mark':['n']*18,
                       'value':np.random.randn(18)})

我有幾個月,那幾個月的幾天,這是一個分類變量的時期。 我還有一個 to_mak 列和一個值列。 我希望通過切片 moth、day 和 period 列,在對 value 列進行排序時,將 'to_mark' 列的值從 'n' 更改為 'y'。

我嘗試的是:

for m in df_test.month.unique():
    for d in df_test[df_test.month==m].day.unique():
        for p in df_test[(df_test.month==m) & (df_test.day==d)].period.unique():
            df_test[(df_test.month==m) & (df_test.day==d) & (df_test.period == p)].sort_values(
                by='value', ascending=False)['to_mark'] = 'y'

但它無法正常工作,我無法更改“to_mark”列的值。

一個輸出示例:

Index month day period to_mark value
0       1    1      a       n  0.840179
1       1    1      a       n -1.349777
2       1    1      b       n  0.122197
3       1    2      a       n  0.276325
4       1    2      a       n  0.257014
5       1    2      b       n  0.351326
6       2    1      b       n -0.552867
7       2    1      a       n -0.614468
8       2    1      a       n -0.474198
9       2    2      b       n -0.439990
10      2    2      b       n  0.046202
11      2    2      b       n  1.601673
12      3    1      a       n -1.609012
13      3    1      a       n  0.382347
14      3    1      b       n  0.164228
15      3    2      a       n  0.176435
16      3    2      a       n -0.627590
17      3    2      a       n -1.834927

所需的輸出是。

Index month day period to_mark value
0       1    1      a       y  0.840179
1       1    1      a       n -1.349777
2       1    1      b       y  0.122197
3       1    2      a       y  0.276325
4       1    2      a       n  0.257014
5       1    2      b       y  0.351326
6       2    1      b       n -0.552867
7       2    1      a       n -0.614468
8       2    1      a       y -0.474198
9       2    2      b       n -0.439990
10      2    2      b       n  0.046202
11      2    2      b       y  1.601673
12      3    1      a       n -1.609012
13      3    1      a       y  0.382347
14      3    1      b       y  0.164228
15      3    2      a       y  0.176435
16      3    2      a       n -0.627590
17      3    2      a       n -1.834927

先感謝您。

IIUC,您只想將每個組的最大值更改為 'y' ..?
使用idxmaxloc來做到這一點:

df_test = pd.DataFrame({'Index': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], 'month': [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3], 'day': [1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2], 'period': ['a', 'a', 'b', 'a', 'a', 'b', 'b', 'a', 'a', 'b', 'b', 'b', 'a', 'a', 'b', 'a', 'a', 'a'], 'to_mark': ['n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n'], 'value': [0.8401790000000001, -1.349777, 0.122197, 0.276325, 0.25701399999999996, 0.351326, -0.552867, -0.614468, -0.47419799999999995, -0.43998999999999994, 0.046202, 1.601673, -1.609012, 0.382347, 0.16422799999999999, 0.17643499999999998, -0.62759, -1.834927]})

df_test.loc[df_test.groupby(['month', 'day', 'period'])['value'].idxmax(), 'to_mark'] = 'y'

[出去]

    Index  month  day period to_mark     value
0       0      1    1      a       y  0.840179
1       1      1    1      a       n -1.349777
2       2      1    1      b       y  0.122197
3       3      1    2      a       y  0.276325
4       4      1    2      a       n  0.257014
5       5      1    2      b       y  0.351326
6       6      2    1      b       y -0.552867
7       7      2    1      a       n -0.614468
8       8      2    1      a       y -0.474198
9       9      2    2      b       n -0.439990
10     10      2    2      b       n  0.046202
11     11      2    2      b       y  1.601673
12     12      3    1      a       n -1.609012
13     13      3    1      a       y  0.382347
14     14      3    1      b       y  0.164228
15     15      3    2      a       y  0.176435
16     16      3    2      a       n -0.627590
17     17      3    2      a       n -1.834927

更新

要更新第 n 大,您可以將groupbynlargest一起nlargest 然后通過merge獲取要更新的索引。:

df_test = pd.DataFrame({'month': [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3], 'day': [1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2], 'period': ['a', 'a', 'b', 'a', 'a', 'b', 'b', 'a', 'a', 'b', 'b', 'b', 'a', 'a', 'b', 'a', 'a', 'a'], 'to_mark': ['n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'n'], 'value': [0.8401790000000001, -1.349777, 0.122197, 0.276325, 0.25701399999999996, 0.351326, -0.552867, -0.614468, -0.47419799999999995, -0.43998999999999994, 0.046202, 1.601673, -1.609012, 0.382347, 0.16422799999999999, 0.17643499999999998, -0.62759, -1.834927]})

n_largest = (df_test.groupby(['month', 'day', 'period'])['value'].nlargest(2).reset_index())

idx = (df_test.reset_index()
       .merge(n_largest, on=['month', 'day', 'period', 'value'],
              how='inner')['index'])

df_test.loc[idx, 'to_mark'] = 'y'

[出去]

    month  day period to_mark     value
0       1    1      a       y  0.840179
1       1    1      a       y -1.349777
2       1    1      b       y  0.122197
3       1    2      a       y  0.276325
4       1    2      a       y  0.257014
5       1    2      b       y  0.351326
6       2    1      b       y -0.552867
7       2    1      a       y -0.614468
8       2    1      a       y -0.474198
9       2    2      b       n -0.439990
10      2    2      b       y  0.046202
11      2    2      b       y  1.601673
12      3    1      a       y -1.609012
13      3    1      a       y  0.382347
14      3    1      b       y  0.164228
15      3    2      a       y  0.176435
16      3    2      a       y -0.627590
17      3    2      a       n -1.834927

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM