连续填充 pandas DataFrame 的新列
Successively filling in a new column of a pandas DataFrame
我想扩展现有的 pandas DataFrame 并依次填充新列:
df = pd.DataFrame({'col1': [1, 2, 3, 4, 5, 6], 'col2': [7, 8, 9, 10, 11, 12]})
df['col3'] = pd.Series(['a' for x in df[:3]])
df['col3'] = pd.Series(['b' for x in df[3:4]])
df['col3'] = pd.Series(['c' for x in df[4:]])
我希望得到如下结果:
col1 col2 col3
0 1 7 a
1 2 8 a
2 3 9 a
3 4 10 b
4 5 11 c
5 6 12 c
但是,我的代码失败了,我得到:
col1 col2 col3
0 1 7 a
1 2 8 a
2 3 9 NaN
3 4 10 NaN
4 5 11 NaN
5 6 12 NaN
怎么了?
每次您执行类似 df['col3'] = pd.Series(['a' for x in df[:3]])
的操作时,您都会将 new pd.Series
分配给列 col3
。另一种方法是单独创建新列,然后将其分配给 df
.
df = pd.DataFrame({'col1': [1, 2, 3, 4, 5, 6], 'col2': [7, 8, 9, 10, 11, 12]})
new_col = ['a' for _ in range(3)] + ['b'] + ['c' for _ in range(4, len(df))]
df['col3'] = pd.Series(new_col)
使用loc
accessor:
df = pd.DataFrame({'col1': [1, 2, 3, 4, 5, 6], 'col2': [7, 8, 9, 10, 11, 12]})
df.loc[:2,'col3'] = 'a'
df.loc[3,'col3'] = 'b'
df.loc[4:,'col3'] = 'c'
df
col1
col2
col3
0
1
7
a
1
2
8
a
2
3
9
a
3
4
10
b
4
5
11
c
5
6
12
c
正如@Amirhossein Kiani 和@Emma 在评论中指出的那样,您永远不会使用 df
本身来赋值,因此无需对其进行切片。由于您可以将列表分配给 DataFrame 列,因此满足以下条件:
df['col3'] = ['a'] * 3 + ['b'] + ['c'] * (len(df) - 4)
您也可以使用numpy.select
来赋值。这个想法是为某些索引范围和相应的 select 值创建一个布尔系列列表。例如,如果 index 小于 3,则 select 'a',如果 index 在 3 和 4 之间,则 select 'b',等等
import numpy as np
df['col3'] = np.select([df.index<3, df.index.to_series().between(3, 4, inclusive='left')], ['a','b'], 'c')
输出:
col1 col2 col3
0 1 7 a
1 2 8 a
2 3 9 a
3 4 10 b
4 5 11 c
5 6 12 c
我想扩展现有的 pandas DataFrame 并依次填充新列:
df = pd.DataFrame({'col1': [1, 2, 3, 4, 5, 6], 'col2': [7, 8, 9, 10, 11, 12]})
df['col3'] = pd.Series(['a' for x in df[:3]])
df['col3'] = pd.Series(['b' for x in df[3:4]])
df['col3'] = pd.Series(['c' for x in df[4:]])
我希望得到如下结果:
col1 col2 col3
0 1 7 a
1 2 8 a
2 3 9 a
3 4 10 b
4 5 11 c
5 6 12 c
但是,我的代码失败了,我得到:
col1 col2 col3
0 1 7 a
1 2 8 a
2 3 9 NaN
3 4 10 NaN
4 5 11 NaN
5 6 12 NaN
怎么了?
每次您执行类似 df['col3'] = pd.Series(['a' for x in df[:3]])
的操作时,您都会将 new pd.Series
分配给列 col3
。另一种方法是单独创建新列,然后将其分配给 df
.
df = pd.DataFrame({'col1': [1, 2, 3, 4, 5, 6], 'col2': [7, 8, 9, 10, 11, 12]})
new_col = ['a' for _ in range(3)] + ['b'] + ['c' for _ in range(4, len(df))]
df['col3'] = pd.Series(new_col)
使用loc
accessor:
df = pd.DataFrame({'col1': [1, 2, 3, 4, 5, 6], 'col2': [7, 8, 9, 10, 11, 12]})
df.loc[:2,'col3'] = 'a'
df.loc[3,'col3'] = 'b'
df.loc[4:,'col3'] = 'c'
df
col1 | col2 | col3 | |
---|---|---|---|
0 | 1 | 7 | a |
1 | 2 | 8 | a |
2 | 3 | 9 | a |
3 | 4 | 10 | b |
4 | 5 | 11 | c |
5 | 6 | 12 | c |
正如@Amirhossein Kiani 和@Emma 在评论中指出的那样,您永远不会使用 df
本身来赋值,因此无需对其进行切片。由于您可以将列表分配给 DataFrame 列,因此满足以下条件:
df['col3'] = ['a'] * 3 + ['b'] + ['c'] * (len(df) - 4)
您也可以使用numpy.select
来赋值。这个想法是为某些索引范围和相应的 select 值创建一个布尔系列列表。例如,如果 index 小于 3,则 select 'a',如果 index 在 3 和 4 之间,则 select 'b',等等
import numpy as np
df['col3'] = np.select([df.index<3, df.index.to_series().between(3, 4, inclusive='left')], ['a','b'], 'c')
输出:
col1 col2 col3
0 1 7 a
1 2 8 a
2 3 9 a
3 4 10 b
4 5 11 c
5 6 12 c