通过创建具有唯一键的新数据帧,将非标准格式数据帧转换为1NF

2024-05-21 15:55:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我不太清楚如何表述这个问题,欢迎提出改进标题的建议

让我们从我那张巨大的桌子开始,里面有很多道具,它们不是任何正常的形式。我使用多个特定于语言的数据集创建此表

+-----+---------+--------+-----+----------+
| 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   |
|        |         |        |
+--------+---------+--------+

我的第一个想法是按KeyLanguage分组,然后将属性(Prob_A,Prob_B)应用于字典。我用groupby('key')[['Prob_A', 'Language']].apply(lambda x: x.values.tolist()).to_dict()试过了。然而,我总是失败,因为我从来没有得到什么东西接近我的桌子上面

第二个想法是分两步进行分组。首先对键进行分组,然后对语言和属性本身进行分组。在列表中收集结果。 最后一个想法是按键和语言分组并迭代所有行。在循环中,也应该为保存语言信息的每个属性收集一组值。但是,我不知道集合的结构应该是什么样子,结果应该是上面的样子

此外,我还阅读了熊猫文档中关于多索引和分类的一些章节,但它不适合我的用例。在过去,我更多地使用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']

Tags: 数据key语言属性delanguageenlight
1条回答
网友
1楼 · 发布于 2024-05-21 15:55:45

创建一个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

示例中的Prop_A中没有Hart

相关问题 更多 >