Разбейте ряд чисел на разные ряды - панды - PullRequest
1 голос
/ 24 мая 2019

У меня есть датафрейм со значениями столбцов, такими как:

 num_range      id      description
'5000-6000'      1        lmn
'6100-6102'      1        lmn
'6363-6363'      3        xyz
'Q7890-Q8000'    2        pqr

Так есть ли способ написать цикл, который будет разбит на строки и даст мне значения, например.для первого значения num_range, что-то вроде этого:

num_range      id      description
   5000          1        lmn
   5001          1        lmn
   5002          1        lmn
   .....        ...       ....
   5999          1        lmn 
   6000          1        lmn
   Q7891         2        pqr
   Q7892         2        pqr
   ...          ...       ...
   Q8000         2        pqr

Как и прежде, я хочу строки для всех значений num_range вместе с id и description.

Ответы [ 2 ]

1 голос
/ 24 мая 2019

Используйте Series.str.findall для получения числовых значений, также работает, если перед нечисловыми значениями, такими как F в последней строке, затем создать серию по спискам и join для оригинала:

print (df)
     num_range  id description
0    5000-5005   1         lmn
1    6100-6102   1         lmn
2    6363-6363   3         xyz
3  Q7890-Q7893   2         pqr


s = df.pop('num_range').str.findall('\d+')
a = [(i, x) for i, (a, b) in s.items() for x in range(int(a), int(b) + 1)]
s = pd.DataFrame(a).set_index(0)[1].rename('num_range')

df = df.join(s)
print (df)
   id description  num_range
0   1         lmn       5000
0   1         lmn       5001
0   1         lmn       5002
0   1         lmn       5003
0   1         lmn       5004
0   1         lmn       5005
1   1         lmn       6100
1   1         lmn       6101
1   1         lmn       6102
2   3         xyz       6363
3   2         pqr       7890
3   2         pqr       7891
3   2         pqr       7892
3   2         pqr       7893

Если необходимо, чтобы первое значение перед числовым первым извлекало эти значения на Series.str.extract, замените - пустую строку и отобразите в списке:

d = df['num_range'].str.extract('(\D+)\d+', expand=False).replace('-','').to_dict()
print (d)
{0: '', 1: '', 2: '', 3: 'Q'}

s = df.pop('num_range').str.findall('\d+')
a = [(i, '{}{}'.format(d.get(i), x)) 
      for i, (a, b) in s.items() for x in range(int(a), int(b) + 1)]
s = pd.DataFrame(a).set_index(0)[1].rename('num_range')

df = df.join(s).reset_index(drop=True)
print (df)
    id description num_range
0    1         lmn      5000
1    1         lmn      5001
2    1         lmn      5002
3    1         lmn      5003
4    1         lmn      5004
5    1         lmn      5005
6    1         lmn      6100
7    1         lmn      6101
8    1         lmn      6102
9    3         xyz      6363
10   2         pqr     Q7890
11   2         pqr     Q7891
12   2         pqr     Q7892
13   2         pqr     Q7893
0 голосов
/ 24 мая 2019

Это немного грубая сила, но объясняет способ сделать это явно.Можно использовать .apply и т. Д. Также причудливо, чтобы вырезать некоторые петли

# going to save it here
newdf = pd.DataFrame()

for _, row in df.iterrows():
   # split num_range and cast to a list of ints
   s, e = [x for x in map(int, row.num_range.split("-"))]

   # need to add one to e cause we need to include it
   for n in range(s, e+1):
       # replace the number on the row you've iterated on.
       row.num_range = n
       newdf = newdf.append(row)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...