I want to do a left assignment of one column’s values between DataFrame slices where the indexes don’t match.
JavaScript
x
15
15
1
df = pd.DataFrame(data=[('A', '20210101', 5.0),
2
('B', '20210101', 3.0),
3
('C', '20210101', 2.0),
4
('A', '20210102', 0.0),
5
('C', '20210102', 0.0),
6
('A', '20210103', 0.0),
7
('C', '20210103', 0.0),
8
('D', '20210103', 0.0)],
9
columns=('Name', 'Date', 'Dollars')).set_index(['Name', 'Date'])
10
dft = df.groupby(df.index.get_level_values('Date'))
11
dates = list(dft.groups.keys())
12
df0 = dft.get_group(dates[0]).reset_index(level=1)
13
df1 = dft.get_group(dates[1]).reset_index(level=1)
14
df2 = dft.get_group(dates[2]).reset_index(level=1)
15
Is there a single expression that will work whether the left slice’s indexes are a subset or a superset of the right slice’s? The following attempt fails when left is a subset:
JavaScript
1
3
1
df0.loc[df1.index, 'Dollars'] = df1.Dollars # Works because every key in df1 is in df0
2
df0.loc[df2.index, 'Dollars'] = df2.Dollars # KeyError: "['D'] not in index"
3
Advertisement
Answer
If you want the missing index in the left DataFrame
You can do a index union on df0.index
and df2.index
by Index.union
followed by reindex()
before assigning values of df2.index
to df0
, as follows:
JavaScript
1
3
1
df0 = df0.reindex(df0.index.union(df2.index))
2
df0.loc[df2.index, 'Dollars'] = df2.Dollars # then this run successfully
3
Result:
JavaScript
1
9
1
print(df0)
2
3
Date Dollars
4
Name
5
A 20210101 0.0
6
B 20210101 3.0
7
C 20210101 0.0
8
D NaN 0.0
9
If you don’t want the missing index in the left DataFrame
JavaScript
1
3
1
commonKeys = df0.index.intersection(df2.index)
2
df0.loc[commonKeys, 'Dollars'] = df2.loc[commonKeys].Dollars
3
Result df0
:
JavaScript
1
6
1
Date Dollars
2
Name
3
A 20210101 0.0
4
B 20210101 3.0
5
C 20210101 0.0
6