【问题标题】:Python Update only 1 column from another dataframe on index valuePython仅更新索引值上另一个数据框中的1列
【发布时间】:2020-10-27 05:28:00
【问题描述】:

我有 2 个数据框 df1 和 df2。 df2 数据帧是我提取的 df1 的子集以进行一些清理。两个数据帧都可以在索引上匹配。我在网站上看到了很多合并。我不想向 df1 添加更多列,并且数据框的大小不同 df1 有 1000 行,而 df2 有 275 行,所以我不想替换整个列。我想用这些数据帧的索引匹配的 df2['AgeBin'] 值更新 df1['AgeBin']。

indexes = df.loc[df.AgeBin.isin(dfage_test.AgeBin.values)].index
df1.at[indexes,'AgeBin'] = df2['AgeBin'].values

这是我想出的,但似乎有一个问题,因为 df 的大小不同

ValueError: Must have equal len keys and value when setting with an iterable

以下是过度简化。 df1 有 26 列,df2 有 12 列,Agebin 是两个 dfs 中的最后一列。这在理论上是我的目标

df2
    AgeBin
0     2 
1     3 
2     1 
3     3 


df1
    AgeBin
0     NaN 
1     NaN 
2     NaN 
3     NaN 

df1 after update
    AgeBin
0     2 
1     3 
2     1 
3     3 

这里是数据框规范

RangeIndex: 1309 entries, 0 to 1308
Data columns (total 26 columns):
 #   Column            Non-Null Count  Dtype   
---  ------            --------------  -----   
 0   PassengerId       1046 non-null   float64 
 1   Survived          714 non-null    category
 2   Pclass            1046 non-null   category
 3   Name              1046 non-null   object  
 4   Sex               1046 non-null   object  
 5   Age               1046 non-null   float64 
 6   SibSp             1046 non-null   float64 
 7   Parch             1046 non-null   float64 
 8   Ticket            1046 non-null   object  
 9   Fare              1046 non-null   float64 
 10  Embarked          1046 non-null   category
 11  FamilySize        1046 non-null   float64 
 12  Surname           1046 non-null   object  
 13  Title             1046 non-null   object  
 14  IsChild           1046 non-null   float64 
 15  isMale            1046 non-null   category
 16  GroupID           1046 non-null   float64 
 17  GroupSize         1046 non-null   float64 
 18  GroupType         1046 non-null   object  
 19  GroupNumSurvived  1046 non-null   float64 
 20  GroupNumPerished  1046 non-null   float64 
 21  LargeGroup        1046 non-null   float64 
 22  SplitFare         1046 non-null   float64 
 23  log10Fare         1046 non-null   float64 
 24  log10SplitFare    1046 non-null   float64 
 25  AgeBin            1046 non-null   category
dtypes: category(5), float64(15), object(6)
memory usage: 221.9+ KB
  

dfageResults.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 263 entries, 5 to 1308
Data columns (total 1 columns):
 #   Column  Non-Null Count  Dtype   
---  ------  --------------  -----   
 0   AgeBin  263 non-null    category
dtypes: category(1)
memory usage: 12.4 KB

这里是分类

67] dfageResults.groupby(["AgeBin"])["AgeBin"].count()
AgeBin
0-14      25
15-29    192
30-44     46
Name: AgeBin, dtype: int64

[68] df.groupby(["AgeBin"])["AgeBin"].count()
AgeBin
0-14     107
15-29    462
30-44    301
45-59    136
60+       40
Name: AgeBin, dtype: int64

【问题讨论】:

  • 能否提供两个数据框的示例数据?
  • 你需要的是df1.combine_first(df2)
  • 我尝试了您的解决方案,但没有成功。感谢您的帮助!

标签: python pandas dataframe


【解决方案1】:

试试:

print('df2')
print(df2)

print('\ndf1')
print(df1)

df1.update(df2)

print('\ndf1 after update')
print(df1)

输出:

df2
  AgeBin
0  2    
1  3    
2  1    
3  3    

df1
   AgeBin
0 NaN    
1 NaN    
2 NaN    
3 NaN    

df1 after update
  AgeBin
0  2    
1  3    
2  1    
3  3   

【讨论】:

  • 您的输出与我想要的结果不符?另外我不确定我是否遵循您的逻辑,我应该如何在 1000 多行上实现您的代码,并获得 275 个可能的结果?
  • 对不起,我之前创建了自己的数据集。我还在不同大小的数据帧上进行了测试,效果很好。
  • 我看到修改后的代码我得到了和上面一样的错误
  • ValueError: 不能用另一个分类,没有相同的类别
  • 抱歉,我认为行数是您的问题的唯一不同之处,而不是列数。
【解决方案2】:

假设df2 中的所有索引都存在于df1 中(我理解就是这种情况)-以下就足够了:

df1.loc[df2.index,:]=df2

如果上述对index 的假设不成立 - 这是另一种选择(结果相同 - 仅更新 df1 中的现有索引):

df1.loc[set(df2.index).intersection(set(df1.index)),:]=df2

样本输出(具有更具代表性的样本数据):

import pandas as pd
import numpy as np

df1=pd.DataFrame({"AgeBin": [1,2,3,'x', np.nan,np.nan,'a']})

df2=pd.DataFrame({"AgeBin": ['new1', 'new2', 123]}, index=[5,2,3])

print(df1)
print(df2)
df1.loc[df2.index,:]=df2
print(df1)

输出:

  AgeBin
0      1
1      2
2      3
3      x
4    NaN
5    NaN
6      a

  AgeBin
5   new1
2   new2
3    123

  AgeBin
0      1
1      2
2   new2
3    123
4    NaN
5   new1
6      a

【讨论】:

  • 这看起来很棒!这也是有道理的。但我得到了错误
  • ValueError: 不能用另一个分类,没有相同的类别
  • 我将 df2 减少到只有 1 列和它的索引,以使这更容易。我还将 df2 列值更改为与 df1 匹配的分类值。但是我仍然遇到错误。如果有帮助,我是 python 3.7.7。
  • 记住 df1 有 26 列,我现在将 df2 减少到 1。
  • 试试df1.loc[df2.index,'AgeBin']=df2
猜你喜欢
  • 1970-01-01
  • 2021-06-11
  • 2021-06-19
  • 1970-01-01
  • 2021-10-23
  • 1970-01-01
  • 2019-11-23
  • 2020-10-11
  • 2022-01-26
相关资源
最近更新 更多