Как разделить значения внутри Dataframe с помощью Python - PullRequest
0 голосов
/ 22 сентября 2018

Мой фрейм данных:

df
Object      quantity
A             3
B             4
C             10
D             11

Мой желаемый результат:

df
Object      quantity
A             3
B             4
C             4
C             4
C             2
D             4
D             4
D             3

Моя цель - разделить значение, хранящееся в столбце "количество", на 4 илименее 4.

Какой метод я могу использовать для решения этой проблемы?Любое предложение будет оценено.

Ответы [ 3 ]

0 голосов
/ 22 сентября 2018

Нечто подобное может работать.Для каждой группы, где количество больше 4, примените функцию, которая разбивает строки и сохраняет их во временном фрейме данных, а затем объединяет все вместе, чтобы получить желаемый результат:

df = pd.DataFrame({'idx': ['A', 'B', 'C', 'D'],
                   'quantity': [3, 4, 10, 11]})

def split_quant(df):
    quantities = ([4]*(df['quantity'].iat[0] // 4)) + [df['quantity'].iat[0] % 4]

    temp = pd.DataFrame({'idx': df['idx'].iat[0],
                         'quantity': quantities
                         }, index=range(len(quantities)))
    temp = temp[temp['quantity']!=0]

    return temp

df_split = df[df['quantity'] > 4].groupby('idx').apply(split_quant)

output = df[df['quantity'] <= 4].append(df_split).reset_index(drop=True)

writer = pd.ExcelWriter('output.xlsx')
output.to_excel(writer, 'Sheet1', index=False)
writer.save()

Вышеприведенное даст вамследующий выходной фрейм данных:

  idx  quantity
0   A         3
1   B         4
2   C         4
3   C         4
4   C         2
5   D         4
6   D         4
7   D         3

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

Я позволил себе провести некоторые временные тесты различных методов.Использование Pandas 'groupby и apply экономит много времени и позволяет избежать вложенных циклов над входными данными (хотя я уверен, что есть еще более быстрый способ, который также может избежать apply ...)

Шахта:

5.49 ms ± 240 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

@ Икбал Басьяр:

22.8 ms ± 1.47 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

@ sobek

17.7 ms ± 922 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
0 голосов
/ 23 сентября 2018

К сожалению, Pandas не поддерживает эту функцию.Поэтому вам нужно создать новый фрейм данных на основе вашего старого фрейма данных.

Для каждого элемента в старом фрейме данных рассчитайте

old_quantity = n * 4 + rest_quantitity

Таким образом, в новом фрейме данных вы добавите n элемент (ы) с количеством 4, плюс один с количеством rest_quantity (если rest_quantity не равно нулю)

df = df = pd.DataFrame({'item': ["A","B","C"], 'qty': [3, 8,11]})
new_df = pd.DataFrame({'Item': [], 'qty': []})

for idx, item in df.iterrows():    
  if item['qty'] > 4 :
      n = item['qty'] // 4
      r = item['qty'] % 4 
      for _ in range(n):
          new_df.loc[len(new_df)] = [item['item'], 4]
      if r > 0 :
          new_df.loc[len(new_df)] = [item['item'], r]
  else :
      new_df.loc[len(new_df)] = [item['item'], item['qty']]

df

    item qty
0   A   3
1   B   8
2   C   11

new_df

   Item qty
0   A   3.0
1   B   4.0
2   B   4.0
3   C   4.0
4   C   4.0
5   C   3.0
0 голосов
/ 22 сентября 2018

Это работает, но что касается панд, это не красиво и не быстро:

df = pd.DataFrame({'idx': ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
                   'quantity': [1., 2., 3., 4., 5., 6., 7.]})

df['factor'] = df.quantity // 4.
df['modulo'] = df.quantity % 4.

res = pd.DataFrame({'idx': [], 'quantity': []})

for idx, row in df.iterrows():
    for idxx in range(int(row.factor)):
        res = res.append({'idx': row.idx, 'quantity': 4.},
                         ignore_index=True)
    if row.modulo > 0:
        res = res.append({'idx': row.idx, 'quantity': row.modulo},
                         ignore_index=True)

In [24]: df
Out[24]: 
  idx  quantity
0   A       1.0
1   B       2.0
2   C       3.0
3   D       4.0
4   E       5.0
5   F       6.0
6   G       7.0

In [22]: res
Out[22]: 
  idx  quantity
0   A       1.0
1   B       2.0
2   C       3.0
3   D       4.0
4   E       4.0
5   E       1.0
6   F       4.0
7   F       2.0
8   G       4.0
9   G       3.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...