如何更快地迭代 DataFrame 中的行?
How to iterate faster over rows in a DataFrame?
我有一个来自 Pandas 的 DataFrame:
import pandas as pd
data = [{'c1':'aaa', 'c2':100, 'c3': 99, 'c4': 0}, {'c1':'bbb','c2':110, 'c3': 89, 'c4': 0},
{'c1':'aaa','c2':NaN,'c3': 93, 'c4': 0},{'c1':'ccc', 'c2':130,'c3': 77, 'c4': 0},
{'c1':'ddd','c2':140,'c3': 54, 'c4': 0}, {'c1':'bbb','c2':NaN,'c3': 76, 'c4': 0},
{'c1':'ddd', 'c2':NaN,'c3': 75, 'c4': 0}]
df = pd.DataFrame(data)
print df
输出:
c1 c2 c3 c4
0 'aaa' 100 99 0
1 'bbb' 110 89 0
2 'aaa' 100 93 0
3 'ccc' 130 77 0
4 'ddd' 140 54 0
5 'bbb' 110 76 0
6 'ddd' 140 75 0
现在,我希望对于匹配列 c1 的每一行,将列 c4 设置为等于匹配第一个字段的另一行的列 c2。结果:
c1 c2 c3 c4
0 'aaa' 100 99 0
1 'bbb' 110 89 0
2 'aaa' 100 93 100
3 'ccc' 130 77 0
4 'ddd' 140 54 0
5 'bbb' 110 76 110
6 'ddd' 140 75 140
这个数据框是一个例子,真实的数据框有更多的列和更多的行(大约 400 万)。我最初的想法是这样的:
for index, row in df.iterrows():
df[df.c1==row.c1].iloc[1].c4= row.c2
只能有另一个匹配行。很明显,使用iterrows这个过程是极其缓慢的。
根据您最近的编辑,您可以使用 df.groupby
填充,然后使用 shift 将值向下移动 1 行,紧跟组:
df['c4'] = df.groupby("c1")['c2'].shift().fillna(df['c4'])
c1 c2 c3 c4
0 'aaa' 100 99 0.0
1 'bbb' 110 89 0.0
2 'aaa' 100 93 100.0
3 'ccc' 130 77 0.0
4 'ddd' 140 54 0.0
5 'bbb' 110 76 110.0
6 'ddd' 140 75 140.0
我有一个来自 Pandas 的 DataFrame:
import pandas as pd
data = [{'c1':'aaa', 'c2':100, 'c3': 99, 'c4': 0}, {'c1':'bbb','c2':110, 'c3': 89, 'c4': 0},
{'c1':'aaa','c2':NaN,'c3': 93, 'c4': 0},{'c1':'ccc', 'c2':130,'c3': 77, 'c4': 0},
{'c1':'ddd','c2':140,'c3': 54, 'c4': 0}, {'c1':'bbb','c2':NaN,'c3': 76, 'c4': 0},
{'c1':'ddd', 'c2':NaN,'c3': 75, 'c4': 0}]
df = pd.DataFrame(data)
print df
输出:
c1 c2 c3 c4
0 'aaa' 100 99 0
1 'bbb' 110 89 0
2 'aaa' 100 93 0
3 'ccc' 130 77 0
4 'ddd' 140 54 0
5 'bbb' 110 76 0
6 'ddd' 140 75 0
现在,我希望对于匹配列 c1 的每一行,将列 c4 设置为等于匹配第一个字段的另一行的列 c2。结果:
c1 c2 c3 c4
0 'aaa' 100 99 0
1 'bbb' 110 89 0
2 'aaa' 100 93 100
3 'ccc' 130 77 0
4 'ddd' 140 54 0
5 'bbb' 110 76 110
6 'ddd' 140 75 140
这个数据框是一个例子,真实的数据框有更多的列和更多的行(大约 400 万)。我最初的想法是这样的:
for index, row in df.iterrows():
df[df.c1==row.c1].iloc[1].c4= row.c2
只能有另一个匹配行。很明显,使用iterrows这个过程是极其缓慢的。
根据您最近的编辑,您可以使用 df.groupby
填充,然后使用 shift 将值向下移动 1 行,紧跟组:
df['c4'] = df.groupby("c1")['c2'].shift().fillna(df['c4'])
c1 c2 c3 c4
0 'aaa' 100 99 0.0
1 'bbb' 110 89 0.0
2 'aaa' 100 93 100.0
3 'ccc' 130 77 0.0
4 'ddd' 140 54 0.0
5 'bbb' 110 76 110.0
6 'ddd' 140 75 140.0