Объединить значения в несколько столбцов на основе связанного значения - PullRequest
0 голосов
/ 21 февраля 2019

С учетом фрейма данных

+----+-------+------+-----------+-----------+---------------+
|    |   Key | ID   | Status1   | Status2   | OrderID       |
|----+-------+------+-----------+-----------+---------------|
|  0 |     1 | A1   | False     | True      | 1234-USF-0025 |
|  1 |     1 | A1   | False     | True      | 1234-USF-0026 |
|  2 |     1 | A1   | False     | True      | 1234-USF-0027 |
|  3 |     2 | A1   | True      | True      | 1234-USF-0025 |
|  4 |     2 | A1   | True      | True      | 1234-USF-0026 |
|  5 |     2 | A1   | True      | True      | 1234-USF-0027 |
|  6 |     3 | A1   | Anything  | True      | 1234-USF-0025 |
|  7 |     3 | A1   | False     | True      | 1234-USF-0026 |
|  8 |     3 | A1   | False     | Anything  | 1234-USF-0027 |
|  9 |     4 | A2   | True      | True      | 1234-USF-0028 |
| 10 |     4 | A2   | True      | True      | 1234-USF-0029 |
| 11 |     4 | A2   | True      | True      | 1234-USF-0030 |
| 12 |     5 | A3   | True      | True      | 1234-USF-0031 |
| 13 |     5 | A3   | True      | True      | 1234-USF-0032 |
| 14 |     5 | A3   | True      | True      | 1234-USF-0033 |
| 15 |     6 | A4   | True      | True      | 1234-USF-0034 |
| 16 |     6 | A4   | True      | True      | 1234-USF-0035 |
| 17 |     6 | A4   | True      | True      | 1234-USF-0036 |
+----+-------+------+-----------+-----------+---------------+

Как преобразовать в список каждый OrderID для ID и объединить Key на основе каждого Status.Если оба значения Stautses имеют значение True, объединенный Keys должен идти в столбец TRUE.Если один из них Flase, Keys должен идти в столбце FALSE.Если либо (или оба) Status отличается от True или False, Key(s) объединяется в столбце Other.

Желаемый результат df

Order ID        ID  TRUE    FALSE  OTHER
1234-USF-0025   A1   2       1       3
1234-USF-0026   A1   2       1,3
1234-USF-0027   A1   2       1       3
1234-USF-0028   A2   4  
1234-USF-0029   A2   4  
1234-USF-0030   A2   4  
1234-USF-0031   A3   5  
1234-USF-0032   A3   5  
1234-USF-0033   A3   5  
1234-USF-0034   A4   6  
1234-USF-0035   A4   6  
1234-USF-0036   A4   6  

То, что я пробовал

df = df.groupby(['OrderID','ID'])['Key'].apply(','.join).reset_index()

+----+---------------+------+-------+
|    | OrderID       | ID   | Key   |
|----+---------------+------+-------|
|  0 | 1234-USF-0025 | A1   | 1,2,3 |
|  1 | 1234-USF-0026 | A1   | 1,2,3 |
|  2 | 1234-USF-0027 | A1   | 1,2,3 |
|  3 | 1234-USF-0028 | A2   | 4     |
|  4 | 1234-USF-0029 | A2   | 4     |
|  5 | 1234-USF-0030 | A2   | 4     |
|  6 | 1234-USF-0031 | A3   | 5     |
|  7 | 1234-USF-0032 | A3   | 5     |
|  8 | 1234-USF-0033 | A3   | 5     |
|  9 | 1234-USF-0034 | A4   | 6     |
| 10 | 1234-USF-0035 | A4   | 6     |
| 11 | 1234-USF-0036 | A4   | 6     |
+----+---------------+------+-------+

Вышесказанное, конечно, приближает меня, но я не уверен, как вырвать Keys в соответствующие столбцы (TRUE, FALSE и OTHER)

Примечания

Ранее я преобразовал столбец Key в строку

Order IDs может дублироваться для IDs, но будет иметь другое значение Keys

1 Ответ

0 голосов
/ 21 февраля 2019

Это рабочее решение, но определенно есть более быстрый и чистый способ сделать это.Сначала я добавляю столбец для вашей логической логики, затем выполняю groupby для сжатия таблицы, затем просматриваю и заполняю столбцы True, False и Other, используя Key и * 1006.* столбцы.Наконец, я удаляю ненужные столбцы и объединяю строки.

import pandas as pd
import numpy as np
# Your dataframe for testing purposes
df = pd.DataFrame({'Key': '1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6'.split(),
                   'ID': 'A1 A1 A1 A1 A1 A1 A1 A1 A1 A2 A2 A2 A3 A3 A3 A4 A4 A4'.split(),
                   'Status1': 'False False False True True True Anything False False True True True True True True True True True'.split(),
                   'Status2': 'True True True True True True True True Anything True True True True True True True True True'.split(),
                   'OrderID': '25 26 27 25 26 27 25 26 27 28 29 30 31 32 33 34 35 36'.split()})



# First we need to do this boolean logic
df["Result"] = ""
for index, row in df.iterrows():
  stat1 = row["Status1"]
  stat2 = row["Status2"]

  if stat1 == "True" and stat2 == "True":
    row["Result"] = "True"
  elif stat1 == "False" and stat2 == "False" or stat1 == "True" and stat2 == "False" or stat1 == "False" and stat2 == "True":
    row["Result"] = "False"
  else:
    row["Result"] = "Other"


# Now we do your group by
df = df.groupby(['OrderID','ID', 'Result'])['Key'].apply(','.join).reset_index()


# Now we populate the columns you wanted populated
df["True"] = ""
df["False"] = ""
df["Other"] = ""
for index, row in df.iterrows():
  if row[row["Result"]]:
    row[row["Result"]] += "," + row["Key"]
  else:
    row[row["Result"]] += row["Key"]
del df['Result']
del df['Key']


# Final we aggregate the rows to flatten it.
df = df.groupby(['OrderID','ID'], as_index=False).agg(lambda x: "%s" % ''.join(x))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...