我想知道是否有最快的代码来替换两个for循环,假设df大小非常大。在我的实际情况中,每个数据帧是200行和25列。
data_df1 = np.array([['Name','Unit','Attribute','Date'],['a','A',1,2014],['b','B',2,2015],['c','C',3,2016],\
['d','D',4,2017],['e','E',5,2018]])
data_df2 = np.array([['Name','Unit','Date'],['a','F',2019],['b','G',2020],['e','H',2021],\
['f','I',2022]])
df1 = pd.DataFrame(data=data_df1)
print('df1:')
print(df1)
df2 = pd.DataFrame(data=data_df2)
print('df2:')
print(df2)
row_df1 = [1,2,5]
col_df1 = [1,3]
row_df2 = [1,2,3]
col_df2 = [1,2]
for i in range(0,len(row_df1)):
for j in range(0, len(col_df1)):
df1.set_value(row_df1[i],col_df1[j], df2.loc[row_df2[i],col_df2[j]])
print('df1 after operation:')
print(df1)
预期产出:
df1:
0 1 2 3
0 Name Unit Attribute Date
1 a A 1 2014
2 b B 2 2015
3 c C 3 2016
4 d D 4 2017
5 e E 5 2018
df2:
0 1 2
0 Name Unit Date
1 a F 2019
2 b G 2020
3 e H 2021
4 f I 2022
df1 after operation:
0 1 2 3
0 Name Unit Attribute Date
1 a F 1 2019
2 b G 2 2020
3 c C 3 2016
4 d D 4 2017
5 e H 5 2021
我试过了:
df1.loc[[1,2,5],[1,3]] = df2.loc[[1,2,3],[1,2]]
print('df1:')
print(df1)
print('df2:')
print(df2)
但结果如下。有意想不到的南。
df1:
0 1 2 3
0 Name Unit Attribute Date
1 a F 1 NaN
2 b G 2 NaN
3 c C 3 2016
4 d D 4 2017
5 e NaN 5 NaN
df2:
0 1 2
0 Name Unit Date
1 a F 2019
2 b G 2020
3 e H 2021
4 f I 2022
提前感谢任何有帮助的人。
答案 0 :(得分:2)
一些清洁:
React.Component
使用def clean_df(df):
df.columns = df.iloc[0]
df.columns.name = None
df = df.iloc[1:].reset_index()
return df
df1 = clean_df(df1)
df1
index Name Unit Attribute Date
0 1 a A 1 2014
1 2 b B 2 2015
2 3 c C 3 2016
3 4 d D 4 2017
4 5 e E 5 2018
df2 = clean_df(df2)
df2
index Name Unit Date
0 1 a F 2019
1 2 b G 2020
2 3 e H 2021
3 4 f I 2022
,指定merge
,以便不考虑其他列。
on=Name
答案 1 :(得分:1)
另一种基于转置数据帧和ffill的合并和删除重复的方法,即
new_df = df1.merge(df2,on=[0],how='outer').T.set_index(0).sort_index()
.ffill().reset_index().drop_duplicates(0,keep='last').T.dropna()
0 2 3 5 0 Attribute Date Name Unit 1 1 2019 a F 2 2 2020 b G 3 3 2016 c C 4 4 2017 d D 5 5 2021 e H
解释
df1.merge(df2,on=[0],how='outer').T.set_index(0).sort_index()
转置数据帧将给出数据帧,以便我们可以应用ffill来填充nan值
1 2 3 4 5 6 0 Attribute 1 2 3 4 5 NaN Date 2014 2015 2016 2017 2018 NaN Date 2019 2020 NaN NaN 2021 2022 Name a b c d e f Unit A B C D E NaN Unit F G NaN NaN H I
.ffill().reset_index().drop_duplicates(0,keep='last')
这将使用先前的行数据填充nan值,并使用子集0的重复数据删除reset_index,并保留最后一行将保留完全填充的行。
0 1 2 3 4 5 6 0 Attribute 1 2 3 4 5 NaN 2 Date 2019 2020 2016 2017 2021 2022 3 Name a b c d e f 5 Unit F G C D H I
.T.dropna()
这将旋转数据帧,删除具有nan值的行,从而产生所需的输出。
答案 2 :(得分:0)
我还发现下面的代码做了我想要的,并且比两个for循环要快得多。
df1.loc[[1,2,5],[1,3]] = df2.loc[[1,2,3],[1,2]].values