use*_*074 6 python numpy vectorization pandas
我有一个pandas数据帧:
| col1 | heading |
|--------|---------|
|heading1| true |
|abc | false |
|efg | false |
|hij | false |
|heading2| true |
|klm | false |
|... | false |
Run Code Online (Sandbox Code Playgroud)
这个数据实际上是"顺序的",我想把它转换成这个结构:
| col1 | Parent |
|---------------------
|heading1| heading1 |
|abc | heading1 |
|efg | heading1 |
|hij | heading1 |
|heading2| heading2 |
|klm | heading2 |
|... | headingN |
Run Code Online (Sandbox Code Playgroud)
我有+ 10M行,所以这个方法需要太长时间:
df['Parent'] = df['col1']
for index, row in df.iterrows():
if row['heading']:
current = row['col1']
else:
row.loc[index, 'Parent'] = current
Run Code Online (Sandbox Code Playgroud)
您对更快的流程有什么建议吗?
您可以使用mask具有ffill:
df.assign(heading=df.col1.mask(~df.col1.str.startswith('heading')).ffill())
Run Code Online (Sandbox Code Playgroud)
col1 heading
0 heading1 heading1
1 abc heading1
2 efg heading1
3 hij heading1
4 heading2 heading2
5 klm heading2
Run Code Online (Sandbox Code Playgroud)
这是通过更换不以启动任何价值heading有NaN,然后填充的最后一个非楠价值前锋:
df.col1.mask(~df.col1.str.startswith('heading'))
Run Code Online (Sandbox Code Playgroud)
0 heading1
1 NaN
2 NaN
3 NaN
4 heading2
5 NaN
Name: col1, dtype: object
Run Code Online (Sandbox Code Playgroud)
df.col1.mask(~df.col1.str.startswith('heading')).ffill()
Run Code Online (Sandbox Code Playgroud)
0 heading1
1 heading1
2 heading1
3 heading1
4 heading2
5 heading2
Name: col1, dtype: object
Run Code Online (Sandbox Code Playgroud)
可能不是一个非常符合熊猫习惯的解决方案,但您可以使用cumsum逻辑列并使用它来获取每行的相应标题。True本质上,我们定义了一个分段常数索引数组,该数组仅针对原始列上的每个值递增heading。
import pandas as pd
# set up some dummy data
df = pd.DataFrame({'heading': [True, False, False, False, True, False, False]},
index=['heading1', 'foo', 'bar', 'baz', 'heading2', 'quux', 'quuz'])
# get every 'heading' index
headings = df.index[df.heading]
# fetch which row corresponds to which 'heading'
indices = df.heading.cumsum() - 1
# fetch the actual headings for each row
df['parent'] = headings[indices]
print(df)
Run Code Online (Sandbox Code Playgroud)
上述代码的输出是
heading parent
heading1 True heading1
foo False heading1
bar False heading1
baz False heading1
heading2 True heading2
quux False heading2
quuz False heading2
Run Code Online (Sandbox Code Playgroud)
您可以从中删除drop不必要的heading列。当然,您可以直接获取您拥有的逻辑数组并使用它:
headline = df.index.str.startswith('heading') # bool Series
headings = df.index[headline]
indices = df.heading.cumsum() - 1
df['parent'] = headings[indices]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
79 次 |
| 最近记录: |