如何根据索引行将 return 值赋给新列
How to return values to new columns based off indexed rows
问题标题可能无法准确反映问题,因为它很难概括。它更容易显示。我正在尝试根据 df 中列的值创建新列。这些值位于间歇性索引点。它们将始终被标记或与其他列相关联。
输入:
import pandas as pd
import numpy as np
k = 5
N = 10
df = pd.DataFrame({ 'Frame' : range(1, N + 1 ,1),
'A_X' : np.random.randint(k, k + 100 , size=N),
'A_Y' : np.random.randint(k, k + 100 , size=N),
'B_X' : np.random.randint(k, k + 100 , size=N),
'B_Y' : np.random.randint(k, k + 100 , size=N),
'C_X' : np.random.randint(k, k + 100 , size=N),
'C_Y' : np.random.randint(k, k + 100 , size=N),
'D_X' : np.random.randint(k, k + 100 , size=N),
'D_Y' : np.random.randint(k, k + 100 , size=N),
'E_X' : np.random.randint(k, k + 100 , size=N),
'E_Y' : np.random.randint(k, k + 100 , size=N),
'Events' : ['nan','A','nan','C','D','A','nan','nan','C','C']})
这导致:
A_X A_Y B_X B_Y C_X C_Y D_X D_Y E_X E_Y Events Frame
0 95 61 76 47 22 38 54 19 64 13 nan 1
1 82 87 87 24 59 31 55 16 101 78 A 2
2 10 25 66 28 70 78 75 19 23 90 nan 3
3 55 64 15 11 46 87 65 51 10 92 C 4
4 53 103 10 65 103 86 24 49 33 34 D 5
5 12 44 89 14 28 26 17 55 64 76 A 6
6 69 24 73 12 84 71 71 76 5 18 nan 7
7 40 35 73 40 78 31 51 33 77 98 nan 8
8 65 69 83 33 20 90 64 12 19 84 C 9
9 24 70 18 96 65 67 73 42 49 78 C 10
前 10 列是 XY 数据。我想 select 适当的 XY 值来创建新列。它们通过 'Events' 列 select 编辑。这些值将始终与其他列相对应。例如事件的第二行是 'A',所以我想从 A 列(A_X、A_Y)的同一索引点获取 X 和 Y 值。 Events 中的下一个值是 C,所以我想要第四行的 (C_X, C_Y) 等。
所以输出将是:
A_X A_Y B_X B_Y C_X C_Y D_X D_Y E_X E_Y Events Frame X Y
0 95 61 76 47 22 38 54 19 64 13 nan 1 nan nan
1 82 87 87 24 59 31 55 16 101 78 A 2 82 87
2 10 25 66 28 70 78 75 19 23 90 nan 3 nan nan
3 55 64 15 11 46 87 65 51 10 92 C 4 46 87
4 53 103 10 65 103 86 24 49 33 34 D 5 24 49
5 12 44 89 14 28 26 17 55 64 76 A 6 12 44
6 69 24 73 12 84 71 71 76 5 18 nan 7 nan nan
7 40 35 73 40 78 31 51 33 77 98 nan 8 nan nan
8 65 69 83 33 20 90 64 12 19 84 C 9 20 90
9 24 70 18 96 65 67 73 42 49 78 C 10 65 67
我试过这样写:
df['X'] = np.where(df['Events'] == ['A'])
df['Y'] = np.where(df['Events'] == ['A'])
然后对每个列字母重复此操作,但这不会起作用,因为它们的标签不同。我考虑将 X 和 Y 合并在一起并将它们标记为 ['A'、'B'、'C'、'D'、'E']。
但我仍然缺少下一步。我没有从 df 返回值。
我不知道你是否可以矢量化,但你可以用迭代来完成
result = pd.DataFrame(None, index=df.index, columns=['X', 'Y'])
for row in df.itertuples():
x, y = f'{row.Events}_X', f'{row.Events}_Y'
if row.Events == 'nan':
result.loc[row.Index, ['X', 'Y']] = [np.nan, np.nan]
else:
result.loc[row.Index, ['X', 'Y']] = row._asdict()[x], row._asdict()[y]
使用np.where
result = pd.DataFrame(None, index=df.index, columns=['X', 'Y'])
for value in df['Events'].unique():
if value == 'nan':
continue
x, y = f'{value}_X', f'{value}_Y'
result[['X', 'Y']] = np.where(df[['Events']] == value, df[[x, y]], result)
X Y
0
1 51 22
2
3 11 77
4 104 88
5 29 70
6
7
8 42 13
9 36 70
这是使用 pd.DataFrame.apply
的替代解决方案:
df['X'] = df.apply(lambda row: row.get(row['Events']+'_X'), axis=1)
df['Y'] = df.apply(lambda row: row.get(row['Events']+'_Y'), axis=1)
结果:
A_X A_Y B_X B_Y C_X C_Y D_X D_Y E_X E_Y Events Frame X Y
0 95 53 59 32 97 71 35 15 80 78 nan 1 NaN NaN
1 94 63 37 92 87 90 97 25 62 14 A 2 94.0 63.0
2 69 83 49 10 59 59 18 98 13 70 nan 3 NaN NaN
3 82 67 91 61 73 90 39 84 7 42 C 4 73.0 90.0
4 59 88 17 65 93 65 63 89 70 49 D 5 63.0 89.0
5 11 79 41 61 75 46 28 101 18 38 A 6 11.0 79.0
6 70 80 103 53 97 42 51 100 82 80 nan 7 NaN NaN
7 5 18 62 92 85 22 10 40 64 67 nan 8 NaN NaN
8 75 91 75 44 7 69 81 102 78 41 C 9 7.0 69.0
9 37 20 54 53 44 51 20 27 7 86 C 10 44.0 51.0
问题标题可能无法准确反映问题,因为它很难概括。它更容易显示。我正在尝试根据 df 中列的值创建新列。这些值位于间歇性索引点。它们将始终被标记或与其他列相关联。
输入:
import pandas as pd
import numpy as np
k = 5
N = 10
df = pd.DataFrame({ 'Frame' : range(1, N + 1 ,1),
'A_X' : np.random.randint(k, k + 100 , size=N),
'A_Y' : np.random.randint(k, k + 100 , size=N),
'B_X' : np.random.randint(k, k + 100 , size=N),
'B_Y' : np.random.randint(k, k + 100 , size=N),
'C_X' : np.random.randint(k, k + 100 , size=N),
'C_Y' : np.random.randint(k, k + 100 , size=N),
'D_X' : np.random.randint(k, k + 100 , size=N),
'D_Y' : np.random.randint(k, k + 100 , size=N),
'E_X' : np.random.randint(k, k + 100 , size=N),
'E_Y' : np.random.randint(k, k + 100 , size=N),
'Events' : ['nan','A','nan','C','D','A','nan','nan','C','C']})
这导致:
A_X A_Y B_X B_Y C_X C_Y D_X D_Y E_X E_Y Events Frame
0 95 61 76 47 22 38 54 19 64 13 nan 1
1 82 87 87 24 59 31 55 16 101 78 A 2
2 10 25 66 28 70 78 75 19 23 90 nan 3
3 55 64 15 11 46 87 65 51 10 92 C 4
4 53 103 10 65 103 86 24 49 33 34 D 5
5 12 44 89 14 28 26 17 55 64 76 A 6
6 69 24 73 12 84 71 71 76 5 18 nan 7
7 40 35 73 40 78 31 51 33 77 98 nan 8
8 65 69 83 33 20 90 64 12 19 84 C 9
9 24 70 18 96 65 67 73 42 49 78 C 10
前 10 列是 XY 数据。我想 select 适当的 XY 值来创建新列。它们通过 'Events' 列 select 编辑。这些值将始终与其他列相对应。例如事件的第二行是 'A',所以我想从 A 列(A_X、A_Y)的同一索引点获取 X 和 Y 值。 Events 中的下一个值是 C,所以我想要第四行的 (C_X, C_Y) 等。
所以输出将是:
A_X A_Y B_X B_Y C_X C_Y D_X D_Y E_X E_Y Events Frame X Y
0 95 61 76 47 22 38 54 19 64 13 nan 1 nan nan
1 82 87 87 24 59 31 55 16 101 78 A 2 82 87
2 10 25 66 28 70 78 75 19 23 90 nan 3 nan nan
3 55 64 15 11 46 87 65 51 10 92 C 4 46 87
4 53 103 10 65 103 86 24 49 33 34 D 5 24 49
5 12 44 89 14 28 26 17 55 64 76 A 6 12 44
6 69 24 73 12 84 71 71 76 5 18 nan 7 nan nan
7 40 35 73 40 78 31 51 33 77 98 nan 8 nan nan
8 65 69 83 33 20 90 64 12 19 84 C 9 20 90
9 24 70 18 96 65 67 73 42 49 78 C 10 65 67
我试过这样写:
df['X'] = np.where(df['Events'] == ['A'])
df['Y'] = np.where(df['Events'] == ['A'])
然后对每个列字母重复此操作,但这不会起作用,因为它们的标签不同。我考虑将 X 和 Y 合并在一起并将它们标记为 ['A'、'B'、'C'、'D'、'E']。
但我仍然缺少下一步。我没有从 df 返回值。
我不知道你是否可以矢量化,但你可以用迭代来完成
result = pd.DataFrame(None, index=df.index, columns=['X', 'Y'])
for row in df.itertuples():
x, y = f'{row.Events}_X', f'{row.Events}_Y'
if row.Events == 'nan':
result.loc[row.Index, ['X', 'Y']] = [np.nan, np.nan]
else:
result.loc[row.Index, ['X', 'Y']] = row._asdict()[x], row._asdict()[y]
使用np.where
result = pd.DataFrame(None, index=df.index, columns=['X', 'Y'])
for value in df['Events'].unique():
if value == 'nan':
continue
x, y = f'{value}_X', f'{value}_Y'
result[['X', 'Y']] = np.where(df[['Events']] == value, df[[x, y]], result)
X Y 0 1 51 22 2 3 11 77 4 104 88 5 29 70 6 7 8 42 13 9 36 70
这是使用 pd.DataFrame.apply
的替代解决方案:
df['X'] = df.apply(lambda row: row.get(row['Events']+'_X'), axis=1)
df['Y'] = df.apply(lambda row: row.get(row['Events']+'_Y'), axis=1)
结果:
A_X A_Y B_X B_Y C_X C_Y D_X D_Y E_X E_Y Events Frame X Y
0 95 53 59 32 97 71 35 15 80 78 nan 1 NaN NaN
1 94 63 37 92 87 90 97 25 62 14 A 2 94.0 63.0
2 69 83 49 10 59 59 18 98 13 70 nan 3 NaN NaN
3 82 67 91 61 73 90 39 84 7 42 C 4 73.0 90.0
4 59 88 17 65 93 65 63 89 70 49 D 5 63.0 89.0
5 11 79 41 61 75 46 28 101 18 38 A 6 11.0 79.0
6 70 80 103 53 97 42 51 100 82 80 nan 7 NaN NaN
7 5 18 62 92 85 22 10 40 64 67 nan 8 NaN NaN
8 75 91 75 44 7 69 81 102 78 41 C 9 7.0 69.0
9 37 20 54 53 44 51 20 27 7 86 C 10 44.0 51.0