Преобразуйте ненормальные форматы данных в 1NF, создав новые фреймы с уникальными ключами - PullRequest
0 голосов
/ 27 апреля 2020

Я не совсем понял, как сформулировать этот вопрос, предложения по улучшению заголовка приветствуются.

Давайте начнем с моей огромной таблицы, в которой несколько реквизитов, которые не в какой-либо нормальной форме. Я создаю эту таблицу из нескольких языковых наборов данных c.

+-----+---------+--------+-----+----------+
| Key | Prop_A  | Prob_B | ... | Language |
+-----+---------+--------+-----+----------+
|   1 | Light   | Stone  |     | EN       |
|   2 | Medium  | Wood   |     | EN       |
|   1 | Leicht  | Stein  |     | DE       |
|   3 | Hard    | Stone  |     | EN       |
|   2 | Mittel  | Holz   |     | DE       |

Я бы сжал их и извлек бы информацию об избыточности в отдельные кадры данных. Таким образом, результат должен быть примерно таким:

Example: with NF
+-----+---------+--------+
| Key | Prop_A  | Prob_B |
+-----+---------+--------+
|   1 | LIGHT   | STONE  |
|   2 | MEDIUM  | WOOD   |
|   3 | HARD    | STONE  |
+-----+---------+--------+

Значения в верхнем регистре представляют первичный ключ таблицы свойств с дискретными значениями

Example: Prop_A Table
+--------+---------+--------+
|  Key   |   EN    |   DE   |
+--------+---------+--------+
| LIGHT  | Light   | Leicht |
| MEDIUM | Medium  | Mittel |
| HARD   | Hard    | Hart   |
|        |         |        |
+--------+---------+--------+

Моей первой идеей было сгруппировать по Key и Language, а затем применить свойства (Prob_A, Prob_B) к словарю. Я попробовал это с groupby('key')[['Prob_A', 'Language']].apply(lambda x: x.values.tolist()).to_dict(). Однако я всегда терпел неудачу, потому что никогда не получал то, что близко к моей таблице выше.

Вторая идея заключалась в группировании в два этапа. Сначала группа по ключам, а затем группа по языку и свойствам. Соберите результат в списке. Последняя идея заключалась в том, чтобы группировать по ключу и языку и перебирать все строки. В l oop значения должны быть собраны в набор для каждого свойства, которое также содержит информацию о языке. Однако я понятия не имею, как должна выглядеть структура коллекции, чтобы результат выглядел так, как указано выше.

Также прочитайте некоторые главы в документах pandas о мультииндексе и категоризации, но он не подходит на мой случай использования. В прошлом я использовал pandas больше для агрегирования по значению цифры 1025 *, а не для преобразования данных.

У меня такое ощущение, что я использую неправильный инструмент (панда) для своей проблемы. В моей голове идея довольно ясна, но я не вижу решения с pandas. Не могли бы вы дать мне несколько идей, как решить эту проблему с помощью панды или другие предложения?

Мой демонстрационный DF выглядит как

lst = [["1",'Light', "Stone", "EN"],["2",'Medium', "Wood", "EN"], ["1",'Leicht', "Stein", "DE"],["3",'Hard', "Stone", "EN"],["2",'Mittel', "Holz", "DE"]]
df = pd.DataFrame(lst,columns= ['Key','Prop_A', 'Prob_B','Language'])
columns = ['Prop_A', 'Prob_B']

1 Ответ

1 голос
/ 27 апреля 2020

Создайте dictionary, где каждый key - это столбец, а содержимое - таблица свойств для каждого столбца, а затем просто измените исходный кадр данных. Поскольку словарь был создан на основе оригинала, никакие ключи не будут пропущены:

columns = ['Prop_A', 'Prob_B']

dfs = {
    col:
    df[['Key', col, 'Language']].pivot(
        columns='Language', values=col, index='Key')
    for col in columns
}

dfs['Prop_A']

#         DE      EN
# Key       
# LIGHT   LEICHT  LIGHT
# MEDIUM  MITTEL  MEDIUM
# HARD    NaN     HARD

df_f = df.query('Language == "EN"')[['Key'] + columns].\
    apply(lambda x: x.str.upper() if x.name in columns else x).\
    drop_duplicates()

df_f

#   Key Prop_A  Prob_B
# 0 1   LIGHT   STONE
# 1 2   MEDIUM  WOOD
# 3 3   HARD    STONE

В примере

нет Hart в Prop_A
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...