Pandas:依赖于另一个值的列
Pandas: Column that is dependent on another value
我有一个 Pandas 数据框,如下所示:
col1 col2 col3 col4
0 5 1 11 9
1 2 3 14 7
2 6 5 54 8
3 11 2 67 44
4 23 8 2 23
5 1 5 9 8
6 9 7 45 71
我想制作第 5 列 (col5),它依赖于 col1 的值并采用其他列之一的值。
这是我想要的样子,但遇到了一些问题。
if col1 < 3:
col5 == col2
elif col1 < 7 & col1 >= 3:
col5 == col3
elif col1 >= 7 & col1 < 50:
col5 == col4
这将产生以下数据帧:
col1 col2 col3 col4 col5
0 5 1 11 9 11
1 2 3 14 7 3
2 6 5 54 8 54
3 11 2 67 44 44
4 23 8 2 23 23
5 97 5 9 8 8
6 9 7 45 71 71
在此先致谢,如果您有任何问题,请告诉我
可以使用多个numpy.where
,如果没有条件是True
(col1 => 50
)被添加最后一个值1
:
df['col5'] = np.where(df['col1'] <3, df['col2'],
np.where((df['col1'] <7) & (df['col1'] >=3 ), df['col3'],
np.where((df['col1'] >=7) & (df['col1'] <50 ), df['col4'], 1)))
print (df)
col1 col2 col3 col4 col5
0 5 1 11 9 11
1 2 3 14 7 3
2 6 5 54 8 54
3 11 2 67 44 44
4 23 8 2 23 23
5 97 5 9 8 1
6 9 7 45 71 71
通过更改值进行编辑:
如果所有值都需要 col4
>=7
:
df['col5'] = np.where(df['col1'] <3, df['col2'],
np.where((df['col1'] <7) & (df['col1'] >=3 ), df['col3'], df['col4']))
print (df)
col1 col2 col3 col4 col5
0 5 1 11 9 11
1 2 3 14 7 3
2 6 5 54 8 54
3 11 2 67 44 44
4 23 8 2 23 23
5 97 5 9 8 8
6 9 7 45 71 71
时间 len(df)=7000
:
In [441]: %timeit df['col51'] = np.where(df['col1'] <3, df['col2'], np.where((df['col1'] <7) & (df['col1'] >=3 ), df['col3'], df['col4']))
The slowest run took 5.31 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 1.25 ms per loop
In [442]: %timeit df["col52"] = df.apply(lambda x: col52(x), axis=1)
1 loop, best of 3: 552 ms per loop
In [443]: %timeit df["col53"] = [col53(c1,c2,c3,c4) for c1,c2,c3,c4 in zip(df.col1,df.col2,df.col3,df.col4)]
100 loops, best of 3: 9.87 ms per loop
时间在 len(df)=70k
In [446]: %timeit df['col51'] = np.where(df['col1'] <3, df['col2'], np.where((df['col1'] <7) & (df['col1'] >=3 ), df['col3'], df['col4']))
100 loops, best of 3: 2.5 ms per loop
In [447]: %timeit df["col52"] = df.apply(lambda x: col52(x), axis=1)
1 loop, best of 3: 5.36 s per loop
In [448]: %timeit df["col53"] = [col53(c1,c2,c3,c4) for c1,c2,c3,c4 in zip(df.col1,df.col2,df.col3,df.col4)]
10 loops, best of 3: 96.3 ms per loop
时间代码:
#change 1000 to 10000 for 70k
df = pd.concat([df]*1000).reset_index(drop=True)
def col52(x):
if x["col1"] < 3:
return x["col2"]
elif x["col1"] >=3 and x["col1"] < 7:
return x["col3"]
elif x["col1"] >= 7 and x["col1"] < 50:
return x["col4"]
def col53(c1,c2,c3,c4):
if c1 < 3:
return c2
elif c1 >=3 and c1 < 7:
return c3
elif c1>= 7 and c1< 50:
return c4
df['col51'] = np.where(df['col1'] <3, df['col2'], np.where((df['col1'] <7) & (df['col1'] >=3 ), df['col3'], df['col4']))
df["col52"] = df.apply(lambda x: col52(x), axis=1)
df["col53"] = [col53(c1,c2,c3,c4) for c1,c2,c3,c4 in zip(df.col1,df.col2,df.col3,df.col4)]
print (df)
一种方法是使用 pd.DataFrame.apply 函数:
def col5(x):
if x["col1"] < 3:
return x["col2"]
elif x["col1"] >=3 and x["col1"] < 7:
return x["col3"]
elif x["col1"] >= 7 and x["col1"] < 50:
return x["col4"]
此函数将数据帧的每一行作为输入。您可以按常规方式访问该行中的各种列值:x["col1"]、x["col2"] 等。
现在,使用用于在每一行或每一列上 运行 自定义函数(如上面的 col5)的应用函数。参数 "axis" 是 1 表示将函数应用于每一行,而参数 "axis" 是 0 表示将函数应用于每一列(在这种情况下, x 具有不同的结构,即它由您的索引而不是列名索引):
df["col5"] = df.apply(lambda x: col5(x), axis=1)
另外,一般来说,apply 可能会非常慢,特别是当你有带有 if-else 块的函数时,因为对于每一行,你的处理器必须决定应该执行 if-else 块中的哪条语句("pipelining" 和 "branch prediction")。不过你在这里应该没问题。
我有一个 Pandas 数据框,如下所示:
col1 col2 col3 col4
0 5 1 11 9
1 2 3 14 7
2 6 5 54 8
3 11 2 67 44
4 23 8 2 23
5 1 5 9 8
6 9 7 45 71
我想制作第 5 列 (col5),它依赖于 col1 的值并采用其他列之一的值。
这是我想要的样子,但遇到了一些问题。
if col1 < 3:
col5 == col2
elif col1 < 7 & col1 >= 3:
col5 == col3
elif col1 >= 7 & col1 < 50:
col5 == col4
这将产生以下数据帧:
col1 col2 col3 col4 col5
0 5 1 11 9 11
1 2 3 14 7 3
2 6 5 54 8 54
3 11 2 67 44 44
4 23 8 2 23 23
5 97 5 9 8 8
6 9 7 45 71 71
在此先致谢,如果您有任何问题,请告诉我
可以使用多个numpy.where
,如果没有条件是True
(col1 => 50
)被添加最后一个值1
:
df['col5'] = np.where(df['col1'] <3, df['col2'],
np.where((df['col1'] <7) & (df['col1'] >=3 ), df['col3'],
np.where((df['col1'] >=7) & (df['col1'] <50 ), df['col4'], 1)))
print (df)
col1 col2 col3 col4 col5
0 5 1 11 9 11
1 2 3 14 7 3
2 6 5 54 8 54
3 11 2 67 44 44
4 23 8 2 23 23
5 97 5 9 8 1
6 9 7 45 71 71
通过更改值进行编辑:
如果所有值都需要 col4
>=7
:
df['col5'] = np.where(df['col1'] <3, df['col2'],
np.where((df['col1'] <7) & (df['col1'] >=3 ), df['col3'], df['col4']))
print (df)
col1 col2 col3 col4 col5
0 5 1 11 9 11
1 2 3 14 7 3
2 6 5 54 8 54
3 11 2 67 44 44
4 23 8 2 23 23
5 97 5 9 8 8
6 9 7 45 71 71
时间 len(df)=7000
:
In [441]: %timeit df['col51'] = np.where(df['col1'] <3, df['col2'], np.where((df['col1'] <7) & (df['col1'] >=3 ), df['col3'], df['col4']))
The slowest run took 5.31 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 1.25 ms per loop
In [442]: %timeit df["col52"] = df.apply(lambda x: col52(x), axis=1)
1 loop, best of 3: 552 ms per loop
In [443]: %timeit df["col53"] = [col53(c1,c2,c3,c4) for c1,c2,c3,c4 in zip(df.col1,df.col2,df.col3,df.col4)]
100 loops, best of 3: 9.87 ms per loop
时间在 len(df)=70k
In [446]: %timeit df['col51'] = np.where(df['col1'] <3, df['col2'], np.where((df['col1'] <7) & (df['col1'] >=3 ), df['col3'], df['col4']))
100 loops, best of 3: 2.5 ms per loop
In [447]: %timeit df["col52"] = df.apply(lambda x: col52(x), axis=1)
1 loop, best of 3: 5.36 s per loop
In [448]: %timeit df["col53"] = [col53(c1,c2,c3,c4) for c1,c2,c3,c4 in zip(df.col1,df.col2,df.col3,df.col4)]
10 loops, best of 3: 96.3 ms per loop
时间代码:
#change 1000 to 10000 for 70k
df = pd.concat([df]*1000).reset_index(drop=True)
def col52(x):
if x["col1"] < 3:
return x["col2"]
elif x["col1"] >=3 and x["col1"] < 7:
return x["col3"]
elif x["col1"] >= 7 and x["col1"] < 50:
return x["col4"]
def col53(c1,c2,c3,c4):
if c1 < 3:
return c2
elif c1 >=3 and c1 < 7:
return c3
elif c1>= 7 and c1< 50:
return c4
df['col51'] = np.where(df['col1'] <3, df['col2'], np.where((df['col1'] <7) & (df['col1'] >=3 ), df['col3'], df['col4']))
df["col52"] = df.apply(lambda x: col52(x), axis=1)
df["col53"] = [col53(c1,c2,c3,c4) for c1,c2,c3,c4 in zip(df.col1,df.col2,df.col3,df.col4)]
print (df)
一种方法是使用 pd.DataFrame.apply 函数:
def col5(x):
if x["col1"] < 3:
return x["col2"]
elif x["col1"] >=3 and x["col1"] < 7:
return x["col3"]
elif x["col1"] >= 7 and x["col1"] < 50:
return x["col4"]
此函数将数据帧的每一行作为输入。您可以按常规方式访问该行中的各种列值:x["col1"]、x["col2"] 等。
现在,使用用于在每一行或每一列上 运行 自定义函数(如上面的 col5)的应用函数。参数 "axis" 是 1 表示将函数应用于每一行,而参数 "axis" 是 0 表示将函数应用于每一列(在这种情况下, x 具有不同的结构,即它由您的索引而不是列名索引):
df["col5"] = df.apply(lambda x: col5(x), axis=1)
另外,一般来说,apply 可能会非常慢,特别是当你有带有 if-else 块的函数时,因为对于每一行,你的处理器必须决定应该执行 if-else 块中的哪条语句("pipelining" 和 "branch prediction")。不过你在这里应该没问题。