Как правильно использовать apply и int внутри значений одного ключа

#python #pandas #string #dataframe #integer

#python #pandas #строка #фрейм данных #целое число

Вопрос:

У меня основной вопрос: я использую следующий скрипт:

 import pandas as pd
from collections import OrderedDict


df = pd.DataFrame({'ID' : ['ID1', 'ID1', "ID1","ID2","ID2"], "pdb" : ["a", "b", "c","d","e"], "beg": [1, 3, 40,111,100], "end" : [11, 12, 50,115,110]})
df2 = pd.DataFrame

for index, row in df.iterrows(): 
    df['var1'] = df.apply(lambda x : " ".join(list(map(str,range(x['beg'],x['end'] 1)))),axis=1)
    df2 = df.groupby(["ID"], sort=False)['var1']
    .apply(lambda x : (' '.join(x.astype(str)))).reset_index(name='var1')  
    df2['var1'] = (df2['var1'].str.split().apply(lambda x: (OrderedDict.fromkeys(x).keys()))
    .str.join(' '))
    df2["var1"] = df2["var1"].map(lambda x: int(x))    
    df2["var2"] = (df2["var1"].str.split().apply(lambda x: sorted(x)).str.join(" "))
 

И я получаю эту ошибку при попытке преобразовать строку чисел в целые числа, чтобы ее можно было правильно отсортировать: (из этой строки: df2["var1"] = df2["var1"].map(lambda x: int(x) )

 ValueError: invalid literal for int() with base 10: '1 10 11 12 2 3 4 40 41 42 43 44 45 46 47 48 49 5 50 6 7 8 9'
 

Есть ли правильный способ сделать это?
Заранее спасибо.

Ответ №1:

Я думаю, вы можете создать новый столбец r с диапазонами, а DataFrame.explode затем отсортировать, удалить дубликаты и преобразовать в строки перед join каждой группой по ID :

 df['r'] = df.apply(lambda x: range(x['beg'],x['end'] 1), axis=1)
df2 = df.explode('r').drop_duplicates(['ID','r']).sort_values(['ID','r'])
df2['r'] = df2['r'].astype(str)
df2 = df2.groupby('ID')['r'].agg(' '.join).reset_index()
print (df2)
    ID                                                  r
0  ID1  1 2 3 4 5 6 7 8 9 10 11 12 40 41 42 43 44 45 4...
1  ID2  100 101 102 103 104 105 106 107 108 109 110 11...
 

В вашем решении это возможно путем сопоставления каждого значения с int, затем сортировки и последнего сопоставления со строками типа:

 df2["var2"] = df2["var1"].str.split().apply(lambda x: ' '.join(list(map(str,sorted(map(int,x))))))