根据多个不同的列条目将系列分配给 pandas 数据框
Assigning a Series to a pandas Dataframe depending on multiple different column entries
我有一个系列和一个 DataFrame:
Series:
1 128
2 112
3 110
其中 Series 索引表示月份
DataFrame
month c1 c2
0 1 a 0
1 2 a 0
2 3 a 0
3 1 b 0
4 2 b 0
5 5 b 0
6 1 c 0
7 2 c 0
8 1 d 0
9 2 d 0
我想应用系列的值,以便月份匹配,但仅限于 c1 具有特定值的地方。
我试过使用
df = ...
series = ...
df.loc[df['c1'] == 'a', 'c2'] = series
但这行不通,因为它没有使用月份作为索引。我怎样才能让它考虑到 DataFrame 中的月份?
Expected Result (c1 = a):
month c1 c2
0 1 a 128
1 2 a 112
2 3 a 110
3 1 b 0
4 2 b 0
5 5 b 0
6 1 c 0
7 2 c 0
8 1 d 0
9 2 d 0
另外,如果我用同一系列申请c1==b,预期结果是这样的(因为没有3月,只有5月)
Expected Result (c1 = b):
month c1 c2
0 1 a 0
1 2 a 0
2 3 a 0
3 1 b 128
4 2 b 112
5 5 b 0
6 1 c 0
7 2 c 0
8 1 d 0
9 2 d 0
为了在两侧使用 Series.map
column month
, if no match replace missing values by Series.fillna
和 downcast='int'
参数进行映射以获得更好的性能过滤器:
m = df['c1'] == 'a'
df.loc[m, 'c2'] = df.loc[m, 'month'].map(series).fillna(0, downcast='int')
print (df)
month c1 c2
0 1 a 128
1 2 a 112
2 3 a 110
3 1 b 0
4 2 b 0
5 5 b 0
6 1 c 0
7 2 c 0
8 1 d 0
9 2 d 0
m = df['c1'] == 'b'
df.loc[m, 'c2'] = df.loc[m, 'month'].map(series).fillna(0, downcast='int')
print (df)
month c1 c2
0 1 a 0
1 2 a 0
2 3 a 0
3 1 b 128
4 2 b 112
5 5 b 0
6 1 c 0
7 2 c 0
8 1 d 0
9 2 d 0
IIUC,使用map
to convert your values from the series, and fillna
处理可能缺失的值,然后赋值,它会自动从索引对齐:
df.loc[df['c1'] == 'b', 'c2'] = df['month'].map(series).fillna(0)
或者,两边切片:
mask = df['c1'] == 'b'
df.loc[mask, 'c2'] = df.loc[mask, 'month'].map(series).fillna(0)
输出:
month c1 c2
0 1 a 0
1 2 a 0
2 3 a 0
3 1 b 128
4 2 b 112
5 5 b 0
6 1 c 0
7 2 c 0
8 1 d 0
9 2 d 0
另一种方法是将您的系列变成一个 df,并将其合并到原始 df,然后用 0 填充 nas,如下所示(并在 'c1' 之后更改 'a' : 在 join_df 中更改要加入的字母):
join_df = pd.DataFrame({'month':series.index,
'c1':['a']*len(series),
'c2':series})
df[['month', 'c1']].merge(join_df, on=['month', 'c1'], how='left').fillna(0)
输出:
month c1 c2
0 1 a 128.0
1 2 a 112.0
2 3 a 110.0
3 1 b 0.0
4 2 b 0.0
5 5 b 0.0
6 1 c 0.0
7 2 c 0.0
8 1 d 0.0
9 2 d 0.0
对于'b',它输出:
month c1 c2
0 1 a 0.0
1 2 a 0.0
2 3 a 0.0
3 1 b 128.0
4 2 b 112.0
5 5 b 0.0
6 1 c 0.0
7 2 c 0.0
8 1 d 0.0
9 2 d 0.0
我有一个系列和一个 DataFrame:
Series:
1 128
2 112
3 110
其中 Series 索引表示月份
DataFrame
month c1 c2
0 1 a 0
1 2 a 0
2 3 a 0
3 1 b 0
4 2 b 0
5 5 b 0
6 1 c 0
7 2 c 0
8 1 d 0
9 2 d 0
我想应用系列的值,以便月份匹配,但仅限于 c1 具有特定值的地方。
我试过使用
df = ...
series = ...
df.loc[df['c1'] == 'a', 'c2'] = series
但这行不通,因为它没有使用月份作为索引。我怎样才能让它考虑到 DataFrame 中的月份?
Expected Result (c1 = a):
month c1 c2
0 1 a 128
1 2 a 112
2 3 a 110
3 1 b 0
4 2 b 0
5 5 b 0
6 1 c 0
7 2 c 0
8 1 d 0
9 2 d 0
另外,如果我用同一系列申请c1==b,预期结果是这样的(因为没有3月,只有5月)
Expected Result (c1 = b):
month c1 c2
0 1 a 0
1 2 a 0
2 3 a 0
3 1 b 128
4 2 b 112
5 5 b 0
6 1 c 0
7 2 c 0
8 1 d 0
9 2 d 0
为了在两侧使用 Series.map
column month
, if no match replace missing values by Series.fillna
和 downcast='int'
参数进行映射以获得更好的性能过滤器:
m = df['c1'] == 'a'
df.loc[m, 'c2'] = df.loc[m, 'month'].map(series).fillna(0, downcast='int')
print (df)
month c1 c2
0 1 a 128
1 2 a 112
2 3 a 110
3 1 b 0
4 2 b 0
5 5 b 0
6 1 c 0
7 2 c 0
8 1 d 0
9 2 d 0
m = df['c1'] == 'b'
df.loc[m, 'c2'] = df.loc[m, 'month'].map(series).fillna(0, downcast='int')
print (df)
month c1 c2
0 1 a 0
1 2 a 0
2 3 a 0
3 1 b 128
4 2 b 112
5 5 b 0
6 1 c 0
7 2 c 0
8 1 d 0
9 2 d 0
IIUC,使用map
to convert your values from the series, and fillna
处理可能缺失的值,然后赋值,它会自动从索引对齐:
df.loc[df['c1'] == 'b', 'c2'] = df['month'].map(series).fillna(0)
或者,两边切片:
mask = df['c1'] == 'b'
df.loc[mask, 'c2'] = df.loc[mask, 'month'].map(series).fillna(0)
输出:
month c1 c2
0 1 a 0
1 2 a 0
2 3 a 0
3 1 b 128
4 2 b 112
5 5 b 0
6 1 c 0
7 2 c 0
8 1 d 0
9 2 d 0
另一种方法是将您的系列变成一个 df,并将其合并到原始 df,然后用 0 填充 nas,如下所示(并在 'c1' 之后更改 'a' : 在 join_df 中更改要加入的字母):
join_df = pd.DataFrame({'month':series.index,
'c1':['a']*len(series),
'c2':series})
df[['month', 'c1']].merge(join_df, on=['month', 'c1'], how='left').fillna(0)
输出:
month c1 c2
0 1 a 128.0
1 2 a 112.0
2 3 a 110.0
3 1 b 0.0
4 2 b 0.0
5 5 b 0.0
6 1 c 0.0
7 2 c 0.0
8 1 d 0.0
9 2 d 0.0
对于'b',它输出:
month c1 c2
0 1 a 0.0
1 2 a 0.0
2 3 a 0.0
3 1 b 128.0
4 2 b 112.0
5 5 b 0.0
6 1 c 0.0
7 2 c 0.0
8 1 d 0.0
9 2 d 0.0