【问题标题】:How to find the row of a dataframe from column value then update row with dictionary?如何从列值中找到数据框的行,然后用字典更新行?
【发布时间】:2019-11-17 01:10:52
【问题描述】:

我有一个表单的数据框:

import pandas as pd
df = pd.DataFrame(None,columns= ['Name','Age','Asset'])
df = df.append({'Name':'John','Age':10,'Asset':'Bike'},ignore_index=True)
df = df.append({'Name':'Sarah','Age':17,'Asset':'Laptop'},ignore_index=True)
df = df.append({'Name':'Noah','Age':14,'Asset':'Book'},ignore_index=True)
df

    Name    Age     Asset
0   John    10  Bike
1   Sarah   17  Laptop
2   Noah    14  Book

现在我想拿一本字典{'Name' :'John','Age':11,'Asset' :'Phone'} 并找到名为 John 的 df 行,将年龄更改为 11 并将资产更改为“电话”。假设数据框的每一列都是字典中的一个键。

由于 iloc 检索到一行,我认为这会起作用,

df.loc[df['Name'] == 'John'] = {'Name' :'John','Age':11,'Asset' :'Phone'}

但是,这不起作用,您需要使用列表进行更新。

用字典更新数据框行的有效方法是什么?

【问题讨论】:

  • df.loc[df['Name'] == 'John'] = pd.Series({'Name' :'John','Age':11,'Asset' :'Phone'})?
  • @QuangHoang 用 Nan 更新姓名、年龄和资产

标签: python-3.x pandas dataframe dictionary


【解决方案1】:

您可以将索引设置为名称,然后调用df.update() 来更新引用匹配索引的数据框。最后.reset_index() 将索引重置为列:

d={'Name' :'John','Age':11,'Asset' :'Phone'}

d_=pd.DataFrame().from_dict(d,'index').T
m_=df.set_index('Name')
m_.update(d_)
df=m_.reset_index()

    Name Age   Asset
0   John  11   Phone
1  Sarah  17  Laptop
2   Noah  14    Book

【讨论】:

  • 即使字典键不在 df 的列名的顺序上,这是否有效?
  • @Qwertford 只要您将Name 设置为索引,顺序就无关紧要。它会工作
  • @Qwertford 你也可以尝试使用pd.concat([d_,df],sort=False).drop_duplicates('Name').reindex(df.columns,axis=1) 来获取无序的字典
【解决方案2】:

我认为您正在尝试对 John 以外的其他内容进行更改?但是对于任何字典?

让我们将您提供的字典设置为

di = {'Name' :'John','Age':11,'Asset' :'Phone'}

然后我们可以使用 .loc 按“姓名”过滤行,并选择“年龄”和“资产”列,然后从字典中设置值。

df.loc[df['Name'] == di['Name'], ['Age', 'Asset']] = [di['Age'], di['Asset']]

print(df)

    Name Age   Asset
0   John  11   Phone
1  Sarah  17  Laptop
2   Noah  14    Book

【讨论】:

  • 难道没有办法将字典键与列名匹配以避免对每个组合进行硬编码? df.append() 接收字典并使用 None 来替换缺失的键值,难道没有类似的东西来更新数据框吗?
  • 见下面的@anky_91,这是更好的答案。恕我直言
【解决方案3】:

您可以将dict.values() 直接分配给您要由.loc 修改的切片,如下所示(注意:这适用于 Python 3.5+,因为d 由插入顺序保证。在 Python collections.OrderedDict):

d = {'Name' :'John','Age':11,'Asset' :'Phone'}
df.loc[df.Name.eq(d['Name']), :] = list(d.values())

Out[643]:
    Name Age   Asset
0   John  11   Phone
1  Sarah  17  Laptop
2   Noah  14    Book

【讨论】:

  • 这不是有风险,因为 list(d.values()) 可能不会按列的顺序为您提供值吗?字典的键可以是任意顺序。
  • Python 3.5+ 保证插入顺序。因此,如果您按照d = {'Name' :'John','Age':11,'Asset' :'Phone'} 中的特定顺序创建字典。保证Name -> Age -> Asset的顺序。但是,如果您无法控制字典的创建方式,这将不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-20
  • 2023-02-24
  • 2018-11-28
  • 2020-07-03
  • 2021-07-14
  • 2020-04-17
相关资源
最近更新 更多