Близлежащие значения столбца таблицы данных в Python



У меня есть фрейм данных с некоторыми столбцами, скажем' n 'столбцов и некоторые строки, скажем' m ' строк. Я хочу сгруппировать строки фрейма данных в зависимости от одного столбца(столбец:'x') значения, это не точное совпадение значений столбца 'x'. Мне нужно сгруппировать близлежащие ценности. Например, мой фрейм данных будет выглядеть так:



      y    yh     x    xw       w   Nxt
0 2987 3129 347 2092 1735.0 501
1 2715 2847 501 1725 1224.0 492
2 2419 2716 490 2196 1704.0 492
3 2310 2373 492 794 302.0 886
4 2309 2370 886 1012 126.0 492
5 2198 2261 497 791 299.0 886
6 2197 2258 886 1010 124.0 492
7 1663 2180 375 1092 600.0 1323


В приведенном выше фрейме данных разница между значениями столбца " x " составляет между 20, тогда мне нужно сгруппировать их в новый фрейм данных, а остальных можно избежать. Здесь индекс=1,2,3,5 строк может быть одна группа и индекс=4,6 будет другой группой, потому что разница между этими строками столбца " x " составляет между 20. Мои ожидаемые выходные данные должны быть тремя фреймами данных - df1: Один содержит все сгруппированные строки и df2: содержит другую группу строк и "df3": остальные строки следующим образом:



Df1:



      y    yh     x    xw       w   Nxt
1 2715 2847 501 1725 1224.0 492
2 2419 2716 490 2196 1704.0 492
3 2310 2373 492 794 302.0 886
5 2198 2261 497 791 299.0 886


Df2:



      y    yh     x    xw       w   Nxt
4 2309 2370 886 1012 126.0 492
6 2197 2258 886 1010 124.0 492


Df3:



    y    yh     x    xw       w   Nxt
0 2987 3129 347 2092 1735.0 501
7 1663 2180 375 1092 600.0 1323


Я пытался использовать Groupby-apply и groupby-transform, но не смог добиться успеха. Было бы очень полезно, если бы кто-нибудь мог помочь мне получить это ожидаемое, Спасибо заранее.

708   2  

2 ответов:

Чтобы сгруппировать значение в столбце " x "в пределах 20, вы можете использовать shift и создать столбец с именем "group", чтобы найти, где все пространство между двумя строками выше 20, как только значения отсортированы по "x".

df = df.sort_values('x')
df.loc[(df.x.shift() < df.x - 20),'group'] = 1 # everytime the jump betweeen two row is more than 20
# use cumsum, ffill and fillna to complete the column group and have a different number for each one
df['group'] = df['group'].cumsum().ffill().fillna(0)
#if the order of indexes matters, you can here add df = df.sort_index() and the code after is the same

С помощью вашего ввода вы получите:

      y    yh    x    xw       w   Nxt  group
0  2987  3129  347  2092  1735.0   501    0.0
7  1663  2180  375  1092   600.0  1323    1.0
2  2419  2716  490  2196  1704.0   492    2.0
3  2310  2373  492   794   302.0   886    2.0
5  2198  2261  497   791   299.0   886    2.0
1  2715  2847  501  1725  1224.0   492    2.0
4  2309  2370  886  1012   126.0   492    3.0
6  2197  2258  886  1010   124.0   492    3.0

Теперь вы можете создать список фреймов данных для каждой группы, если в группе имеется более одной строки. Вам нужно использовать groupby на 'x', filter группу с длиной больше 1. В конце добавьте всю группу с a длина один как один кадр данных:

list_df = [df_g for name_g, df_g in df.groupby('group').filter(lambda x: len(x)>1).groupby('group')] +\
            [df.groupby('group').filter(lambda x: len(x)==1)]

И вы заканчиваете тем, что каждый элемент списка является одним из фреймов данных, которые вы хотите, например.

print (list_df [0])
      y    yh    x    xw       w  Nxt  group
2  2419  2716  490  2196  1704.0  492    2.0
3  2310  2373  492   794   302.0  886    2.0
5  2198  2261  497   791   299.0  886    2.0
1  2715  2847  501  1725  1224.0  492    2.0

Или

print (list_df [-1])
      y    yh    x    xw       w   Nxt  group
0  2987  3129  347  2092  1735.0   501    0.0
7  1663  2180  375  1092   600.0  1323    1.0

Я вижу, что вам нужно имя для каждого из них, но я думаю, что будет легче получить к ним доступ, если они будут в списке

Я сделал реализацию проблемы из того, что я понял.

group = df.groupby("x").groups

def neighbour(temp):
    temp_final = []
    final = []
    for i in range(len(temp)):
        t = []
        for j in range(len(temp)):
            if abs(temp[i] - temp[j]) <= 20:
                t.append(temp[j])
            else:
                pass
        t = sorted(t)
        temp_final.append(t)

    temp_final = list(set(frozenset(sublist) for sublist in final))
    for i in range(len(temp_final)):
        u = []
        for item in temp_final[i]:
            u.append(item)
        final.append(u)

    return final

dataframes = {}
for i in range(len(val)):
    key_name = "dataframe_"+str(i)
    dg = pd.DataFrame()
    for item in val[i]:
        index = list(group[item])
        for i in range(len(index)):
            dg = dg.append(df.iloc[index[i]])

    dataframes[key_name] = dg
Пожалуйста, дайте мне знать в случае любого неправильного толкования.
dataframes

{'dataframe_0':      Nxt       w      x      xw       y      yh
5  886.0   299.0  497.0   791.0  2198.0  2261.0
2  492.0  1704.0  490.0  2196.0  2419.0  2716.0
3  886.0   302.0  492.0   794.0  2310.0  2373.0
1  492.0  1224.0  501.0  1725.0  2715.0  2847.0, 'dataframe_1':       Nxt
w      x      xw       y      yh
0   501.0  1735.0  357.0  2092.0  2987.0  3129.0
7  1323.0   600.0  375.0  1092.0  1663.0  2180.0, 'dataframe_2':      Nxt      
w      x      xw       y      yh
4  492.0  126.0  886.0  1012.0  2309.0  2370.0
6  492.0  124.0  886.0  1010.0  2197.0  2258.0}

Вот результат.

Comments

    Ничего не найдено.