Python 基于关键字的单步数据帧
我有一个Python 基于关键字的单步数据帧,python,pandas,Python,Pandas,我有一个pandas数据框 In [97]: df Out[97]: A1 A1_step A1_step_n LB7 dF 0 40000 500 2 4 2 1 60000 300 3 6 7 我想使用包含step和step\n关键字的列来“逐步”(迭代)遍历具有指定步长的数据帧行。因此,在上面的示例数据框中,我想对A1列的40000行迭代两次,步骤为500,对60000行迭代三次,步骤为3
pandas
数据框
In [97]: df
Out[97]:
A1 A1_step A1_step_n LB7 dF
0 40000 500 2 4 2
1 60000 300 3 6 7
我想使用包含step
和step\n
关键字的列来“逐步”(迭代)遍历具有指定步长的数据帧行。因此,在上面的示例数据框中,我想对A1
列的40000行迭代两次,步骤为500,对60000行迭代三次,步骤为300。最后,我希望数据帧看起来像
In [98]: df2
Out[98]:
A1 LB7 dF
0 40000 4 2
1 40500 4 2
2 60000 6 7
3 60300 6 7
4 60600 6 7
其中执行了LB7
和dF
的值,不再需要“步骤”列
我已经尝试过在列中循环,试图找出哪些列被循环,并通过这些循环添加到数据帧中,但它很快就会变得非常混乱,我希望这里的人能引导我走上一条更好的道路。您可以在行中循环并手动构建数据帧,如下所示:
dfs = []
col_step = df.columns.str.extract('(.*\_step$)', expand=False).dropna()[0]
col_step_n = df.columns.str.extract('(.*\_step\_n$)', expand=False).dropna()[0]
for i, row in df.iterrows():
start = row['A1']
steps = row[col_step_n]
size = row[col_step]
stop = start + size * (steps)
df_cur = pd.DataFrame({'A1': np.arange(start, stop, size), 'LB7':row['LB7'], 'dF':row['dF']})
dfs.append(df_cur)
df_final = pd.concat(dfs, ignore_index=True)
输出
print(df_final)
A1 LB7 dF
0 40000 4 2
1 40500 4 2
2 60000 6 7
3 60300 6 7
4 60600 6 7
我想分享我最终同意的答案,因为它表明了我所寻求的普遍性水平
import pandas as pd
from itertools import product
dfs = []
step_cols = [col[:-7] for col in df.columns if '_step_n' in col]
const_cols = ([col + '_step' for col in step_cols] + step_cols +
[col + '_step_n' for col in step_cols])
for i, row in df.iterrows():
ranges = []
for col in step_cols:
start = row[col]
stop = row[col] + row[col + '_step'] * row[col + '_step_n']
step = row[col + '_step']
ranges.append(list(range(start, stop, step)))
combos = list(product(*ranges))
dfs.append(pd.DataFrame(
{**{k: v for k, v in zip(step_cols, zip(*combos))},
**df.drop(const_cols, axis=1).iloc[i].to_dict()}))
df2 = pd.concat(dfs, ignore_index=True)
因此,如果原始df
为
In [226]: df
Out[226]:
A1 LB7 dF A1_step_n A1_step
0 40000 4 2 2 500
1 60000 6 7 3 300
In [227]: df2
Out[227]:
A1 LB7 dF
0 40000 4 2
1 40500 4 2
2 60000 6 7
3 60300 6 7
4 60600 6 7
In [230]: df
Out[230]:
A1 LB7 dF A1_step_n A1_step dF_step_n dF_step
0 100 5 15 4 50 2 7
1 200 8 30 3 30 3 4
生成的df2
为
In [226]: df
Out[226]:
A1 LB7 dF A1_step_n A1_step
0 40000 4 2 2 500
1 60000 6 7 3 300
In [227]: df2
Out[227]:
A1 LB7 dF
0 40000 4 2
1 40500 4 2
2 60000 6 7
3 60300 6 7
4 60600 6 7
In [230]: df
Out[230]:
A1 LB7 dF A1_step_n A1_step dF_step_n dF_step
0 100 5 15 4 50 2 7
1 200 8 30 3 30 3 4
这还有一个额外的好处,即在附加列名上加上“_step”和“_step_n”可以让您迭代笛卡尔乘积。例如,如果原始
df
是
In [226]: df
Out[226]:
A1 LB7 dF A1_step_n A1_step
0 40000 4 2 2 500
1 60000 6 7 3 300
In [227]: df2
Out[227]:
A1 LB7 dF
0 40000 4 2
1 40500 4 2
2 60000 6 7
3 60300 6 7
4 60600 6 7
In [230]: df
Out[230]:
A1 LB7 dF A1_step_n A1_step dF_step_n dF_step
0 100 5 15 4 50 2 7
1 200 8 30 3 30 3 4
生成的df2
将迭代A1
和dF
In [231]: df2
Out[231]:
A1 LB7 dF
0 100 5 15
1 100 5 22
2 150 5 15
3 150 5 22
4 200 5 15
5 200 5 22
6 250 5 15
7 250 5 22
8 200 8 30
9 200 8 34
10 200 8 38
11 230 8 30
12 230 8 34
13 230 8 38
14 260 8 30
15 260 8 34
16 260 8 38
谢谢,这很有帮助。我应该补充说,虽然我不知道列名的先验知识,只是有一些与“\u步骤”和“\u步骤\n”附加到名称。也就是说,我想我应该可以从这里开始。我将把这个问题保留一段时间,以防其他人(或你自己)给出一个解决方案,其中包括首先查找哪些列有“\u step”和“\u step\n”。你应该能够使用正则表达式提取列字符串名称。上述修复应该可以工作。