繁体   English   中英

将两个pandas数据帧的值相互组合并完成

[英]Combine and complete values of two pandas dataframes from each other

我有2个数据帧,缺少值,我想合并并完成彼此的数据,

简单的可视化:

df1 :
A,B,C
A1,B1,C1
A2,B2,
A3,B3,C3 

df2 :
A,B,C
A1,,C1
A4,B4,C4
A2,B2,C2

The result wanted:
A,B,C
A1,B1,C1
A2,B2,B2
A3,B3,C3
A4,B4,C4

基本上合并数据帧而不复制“A”列,并通过比较数据帧之间相同列“A”的值来完成行中是否存在缺失值。

我在Stackexchange上的Pandas文档+解决方案上尝试过很多东西,但每次都失败了

这些都是我尝试过的不同之处:

pd.merge_ordered(df1, df2, fill_method='ffill', left_by='A')
df1.combine_first(df2)
df1.update(df2)
pd.concat([df1, df2])
pd.merge(df1, df2, on=['A','B','C'], how='right')
pd.merge(df1, df2, on=['A','B','C'], how='outer')
pd.merge(df1, df2, on=['A','B','C'], how='left')
df1.join(df2, how='outer')
df1.join(df2, how='left')
df1.set_index('A').join(df2.set_index('A'))

(你可以看到我最后非常绝望)

知道怎么做吗?

您是否尝试将combine_firstA作为索引?

df1.set_index('A').combine_first(df2.set_index('A')).reset_index()

    A   B   C
0  A1  B1  C1
1  A2  B2  C2
2  A3  B3  C3
3  A4  B4  C4

或者你可以first使用

pd.concat([df1,df2]).replace('',np.nan).groupby('A',as_index=False).first()
Out[53]: 
    A   B   C
0  A1  B1  C1
1  A2  B2  C2
2  A3  B3  C3
3  A4  B4  C4

设定
既然你把它们写成csvs,我会假设它们是csvs。

df1 = pd.read_csv('df1.csv', sep=',', index_col=0)
df2 = pd.read_csv('df2.csv', sep=',', index_col=0)


使用fillna有使用后align

pd.DataFrame.fillna(*df1.align(df2))

     B   C
A         
A1  B1  C1
A2  B2  C2
A3  B3  C3
A4  B4  C4

如果你坚持,你可以使用reset_index ,但我认为保持reset_index是更漂亮的。

您可以使用pandas 分类数据类型来设置有序的类别列表,对这些有序类别进行排序,以及删除具有Null值的行以获得所需的结果:

from pandas.api.types import CategoricalDtype
# Create first dataframe from OP values
df1 = pd.DataFrame({'A': ['A1', 'A2', 'A3'],
                    'B': ['B1', 'B2', 'B3'],
                    'C': ['C1', '', 'C3']})

# create second dataframe from original values
df2 = pd.DataFrame({'A': ['A1', 'A4', 'A2'],
                    'B': ['', 'B4', 'B2'],
                    'C': ['C1', 'C4', 'C2']})

# concatenate the two together for a long dataframe
final = pd.concat([df1, df2])

# specify the letters in your dataset  
letters = ['A', 'B', 'C']
# create a placeholder dictionary to store the categorical datatypes
cat_dict = {}

# iterate over the letters
for let in letters:
    # create the ordered categories - set hte range for the max # of values
    cats = ['{}{}'.format(let, num) for num in list(range(1000))]
    # create ordered categorical datatype
    cat_type = CategoricalDtype(cats, ordered=True)
    # insert into placeholder
    cat_dict[let] = cat_type

# properly format your columns as the ordered categories
final['A'] = final['A'].astype(cat_dict['A'])
final['B'] = final['B'].astype(cat_dict['B'])
final['C'] = final['C'].astype(cat_dict['C'])
# finally sort on the three columns and drop rows with NA values
final.sort_values(['A', 'B', 'C']).dropna(how='any')

# which outputs desired results
    A   B   C
0  A1  B1  C1
2  A2  B2  C2
2  A3  B3  C3
1  A4  B4  C4

虽然这有点长,但这样做的一个好处是你的数据可以在输入时以任何顺序。 这会将继承等级插入每列中的值,因此A1 <A2 <A3,依此类推。 这也使您可以对列进行排序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM