2
Category    Data     Age
A1            30     {'Age1_Set': 25.6, 'WIndex': 343.3, 'Age2_Set': 22.6}
A2            20     {'Age1_Set': 35.2, 'WIndex': 343.3, 'Age2_Set': 42.1}
A3            20     {'Age1_Set': 26.5, 'WIndex': 343.3, 'Age2_Set': 11.1}

我的 pandas df 就像上面一样。年龄应该是“Age1_Set”和“Age2_Set”的最小值。如果 Age 不是字典而是三列,我能够处理这个问题。

我的输出是:

Category    Data     Age
A1            30     22.6
A2            20     35.2
A3            20     11.1

如何才能做到这一点?

编辑:我在原始 df 中有另一个条目

Category    Data     Age
A4            20    

年龄基本上是空的。如何处理这种情况。

4

4 回答 4

3

从列中的字典创建一个新的数据框Age,然后filter使用Age类似的列并使用从 和min获取axis=1最小年龄:Age1_SetAge2_Set

df['Age'] = pd.DataFrame(df['Age'].tolist()).filter(like='Age').min(1)

或者,您也可以使用Series.str.get+ np.minimum

df['Age'] = np.minimum(df['Age'].str.get('Age1_Set'), df['Age'].str.get('Age2_Set'))

  Category  Data   Age
0       A1    30  22.6
1       A2    20  35.2
2       A3    20  11.1
于 2020-10-09T13:20:42.703 回答
2

如果只需要比较dict的这两个值,可以使用如下方法:

df['Age']=df['Age'].apply(lambda x: min(x["Age1_Set"], x["Age2_Set"]))

这避免了将字典转换为其他数据格式的麻烦,并且 IMO 易于阅读。

如果您需要更复杂的逻辑,那么您可能希望将 lambda 提取到它自己的函数中。例如,当您需要处理 None 的条目时:

def get_min_age(entry:dict)->float:
    if entry is None:
        return 0
    else:
        return min(entry["age1"], entry["age2"])
df['Age']=df['Age'].apply(get_min_age)

性能说明:

.apply()在处理大型数据集(>100k 行)时,使用不是一种理想的方法,因为它以顺序方式处理每一行。

如果您注意到性能成为瓶颈,则其他答案中的矢量化方法将具有更高的性能(正如本文更详细解释的那样)。

于 2020-10-09T13:29:42.490 回答
1

你可以试试:

df = pd.DataFrame({"Category": ["A1", "A2", "A3"],
                   "Data": [30, 20, 20],
                   "Age": [{'Age1_Set': 25.6, 'WIndex': 343.3, 'Age2_Set': 22.6}, {'Age1_Set': 35.2, 'WIndex': 343.3, 'Age2_Set': 42.1}, {'Age1_Set': 26.5, 'WIndex': 343.3, 'Age2_Set': 11.1}]})

df["Min_Age"] = [min(x["Age1_Set"], x["Age2_Set"]) for x in df.Age]

print(df)

结果:

  Category  Data                                                Age  Min_Age
0       A1    30  {'Age1_Set': 25.6, 'WIndex': 343.3, 'Age2_Set'...     22.6
1       A2    20  {'Age1_Set': 35.2, 'WIndex': 343.3, 'Age2_Set'...     35.2
2       A3    20  {'Age1_Set': 26.5, 'WIndex': 343.3, 'Age2_Set'...     11.1
于 2020-10-09T13:41:56.307 回答
0

您可以只传递您的数据列而无需任何额外的参数。

import pandas as pd

df2 = pd.json_normalize(df['Age'])
于 2020-10-09T13:10:17.350 回答