Как выбрать информацию строки в кадре данных по идентификатору - PullRequest
2 голосов
/ 04 марта 2020

Я новичок в python. У меня есть большой массив данных, подобный этому:

    ID  x   y
0   1   x1  y1
1   0   x2  y2
2   0   x3  y3
3   2   x4  y4
4   1   x5  y5
5   2   x6  y6

Я хотел бы взять пары (x; y) между идентификаторами 1 и 2, в таком кадре данных:

    coordinates
0   (x1,y1), (x2,y2), (x3,y3), (x4,y4)
1   (x5,y5), (x6,y6)

Я уже пробовал удваивать для итерации, но это долго вычислять. Как я могу получить эту вещь?

Ответы [ 2 ]

3 голосов
/ 04 марта 2020

Одна идея - создать группы по каждому 1 начальному значению и агрегировать пользовательскую лямбда-функцию для кортежей:

df['new'] = (df['ID'] == 1).cumsum()
print (df)
   ID   x   y  new
0   1  x1  y1    1
1   0  x2  y2    1
2   0  x3  y3    1
3   2  x4  y4    1
4   1  x5  y5    2
5   2  x6  y6    2

df1 = (df.groupby('new')['x','y']
         .apply(lambda x: list(map(tuple, x.values.tolist())))
         .reset_index(name='coordinates'))
print (df1)
   new                               coordinates
0    1  [(x1, y1), (x2, y2), (x3, y3), (x4, y4)]
1    2                      [(x5, y5), (x6, y6)]

Аналогичное решение без нового столбца:

df1 = (df.groupby((df['ID'].rename('new') == 1).cumsum())['x','y']
         .apply(lambda x: list(map(tuple, x.values.tolist())))
         .reset_index(name='coordinates'))
print (df1)
   new                               coordinates
0    1  [(x1, y1), (x2, y2), (x3, y3), (x4, y4)]
1    2                      [(x5, y5), (x6, y6)]

РЕДАКТИРОВАТЬ:

print (df)
   ID   x   y
0   1  x1  y1
1   0  x2  y2
2   0  x3  y3
3   2  x4  y4
4   0  x7  y7
4   0  x8  y8
4   1  x5  y5
5   2  x6  y6

g = df['ID'].eq(1).cumsum()
s = df['ID'].shift().eq(2).cumsum()

df = df[s.groupby(g).transform('min').eq(s)]
print (df)
   ID   x   y
0   1  x1  y1
1   0  x2  y2
2   0  x3  y3
3   2  x4  y4
4   1  x5  y5
5   2  x6  y6

df1 = (df.groupby((df['ID'].rename('new') == 1).cumsum())['x','y']
         .apply(lambda x: list(map(tuple, x.values.tolist())))
         .reset_index(name='coordinates'))
print (df1)
   new                               coordinates
0    1  [(x1, y1), (x2, y2), (x3, y3), (x4, y4)]
1    2                      [(x5, y5), (x6, y6)]
2 голосов
/ 04 марта 2020

Вы можете использовать apply кортеж по оси 1 и groupby ваши "группы", используя cumsum с eq(1) и использовать list агрегацию :

(df[['x', 'y']].apply(tuple, axis=1)
 .groupby(df['ID'].eq(1).cumsum()).agg(list))

[out]

ID
1    [(x1, y1), (x2, y2), (x3, y3), (x4, y4)]
2                        [(x5, y5), (x6, y6)]
dtype: object

или, если ожидаемый результат - через запятую строка координат, вы можете apply join функция:

(df[['x', 'y']].apply(tuple, axis=1).astype(str)
 .groupby(df['ID'].eq(1).cumsum()).apply(', '.join))

[out]

ID
1    ('x1', 'y1'), ('x2', 'y2'), ('x3', 'y3'), ('x4', 'y4')
2                                ('x5', 'y5'), ('x6', 'y6')
dtype: object
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...