在特定条件下删除行 pandas(枚举)
Deleting rows on specific condition pandas (enumeration)
我有一个 CSV 文件,其中有一列名为位置。大多数行遵循列位置总是从 1-6 开始的模式(参见例如 - 第 1-12 行)。但是,对于某些行,枚举没有上升到 6,但已经停止在 4,并且位置 1 的新行开始。在这种情况下,我想删除位置为 1-4 的这些行(参见例如 - 第 13-16 行)。
Example:
index position
row 1: 1
row 2: 2
...
row 6: 6
row 7: 1
...
row 12: 6
row 13: 1
row 14: 2
row 15: 3
row 16: 4
row 17: 1
...
row 22: 6
非常感谢任何建议:)
您可以使用以下代码片段来解决问题。这个想法是首先找到位置为 1-4 的行,然后为行创建一个删除列表。最后放下它们,就这样了。
import pandas as pd
import numpy as np
df = pd.DataFrame({
"position": np.concatenate([
list(range(1,7)),
list(range(1,7)),
list(range(1,5)),
list(range(1,7)),
list(range(1,5))
])
})
df = df.append({'position': 1}, ignore_index=True)
df['diff_trail'] = df.position.diff()
rm_index_pos = df[df.diff_trail == -3].index - 1
# We know that 12-15 and 22-25 should be deleted
rm_index = np.ravel([list(range(i,i-4,-1)) for i in rm_index_pos])
rm_index = np.append(rm_index, df.index[-1])
print(rm_index)
df.drop(rm_index, axis=0, inplace=True) # Remove the unwanted rows.
df.drop(['diff_trail'], axis=1, inplace=True) # remove 'diff_trail' column from dataframe.
# Reset the index values.
df.reset_index(drop=True, inplace=True)
print(df)
如果这种模式始终存在,您可以对一些解决方案进行硬编码:每当您在 4 之后遇到 1,将前 4 个索引放入要删除的索引列表中。这不是最漂亮的代码,但它确实有效。
import pandas as pd
df = pd.DataFrame({'position':
[1,2,3,4,5,6,
1,2,3,4,5,6,
1,2,3,4,
1,2,3,4,5,6]})
# every time you encounter a 1 after a 4, delete the previous four columns
index_delete = []
for index, values in enumerate(df.position.values[1:]):
if (values == 1) and (df.position.values[1:][index - 1] == 4):
index_delete.extend([index-3, index-2, index-1, index])
df = df.drop(index_delete)
输入:
df
position
0 1
1 2
2 3
3 4
4 5
5 6
6 1
7 2
8 3
9 4
10 5
11 6
12 1
13 2
14 3
15 4
16 1
17 2
18 3
19 4
20 5
21 6
输出:
df
position
0 1
1 2
2 3
3 4
4 5
5 6
6 1
7 2
8 3
9 4
10 5
11 6
16 1
17 2
18 3
19 4
20 5
21 6
我有一个 CSV 文件,其中有一列名为位置。大多数行遵循列位置总是从 1-6 开始的模式(参见例如 - 第 1-12 行)。但是,对于某些行,枚举没有上升到 6,但已经停止在 4,并且位置 1 的新行开始。在这种情况下,我想删除位置为 1-4 的这些行(参见例如 - 第 13-16 行)。
Example:
index position
row 1: 1
row 2: 2
...
row 6: 6
row 7: 1
...
row 12: 6
row 13: 1
row 14: 2
row 15: 3
row 16: 4
row 17: 1
...
row 22: 6
非常感谢任何建议:)
您可以使用以下代码片段来解决问题。这个想法是首先找到位置为 1-4 的行,然后为行创建一个删除列表。最后放下它们,就这样了。
import pandas as pd
import numpy as np
df = pd.DataFrame({
"position": np.concatenate([
list(range(1,7)),
list(range(1,7)),
list(range(1,5)),
list(range(1,7)),
list(range(1,5))
])
})
df = df.append({'position': 1}, ignore_index=True)
df['diff_trail'] = df.position.diff()
rm_index_pos = df[df.diff_trail == -3].index - 1
# We know that 12-15 and 22-25 should be deleted
rm_index = np.ravel([list(range(i,i-4,-1)) for i in rm_index_pos])
rm_index = np.append(rm_index, df.index[-1])
print(rm_index)
df.drop(rm_index, axis=0, inplace=True) # Remove the unwanted rows.
df.drop(['diff_trail'], axis=1, inplace=True) # remove 'diff_trail' column from dataframe.
# Reset the index values.
df.reset_index(drop=True, inplace=True)
print(df)
如果这种模式始终存在,您可以对一些解决方案进行硬编码:每当您在 4 之后遇到 1,将前 4 个索引放入要删除的索引列表中。这不是最漂亮的代码,但它确实有效。
import pandas as pd
df = pd.DataFrame({'position':
[1,2,3,4,5,6,
1,2,3,4,5,6,
1,2,3,4,
1,2,3,4,5,6]})
# every time you encounter a 1 after a 4, delete the previous four columns
index_delete = []
for index, values in enumerate(df.position.values[1:]):
if (values == 1) and (df.position.values[1:][index - 1] == 4):
index_delete.extend([index-3, index-2, index-1, index])
df = df.drop(index_delete)
输入:
df
position
0 1
1 2
2 3
3 4
4 5
5 6
6 1
7 2
8 3
9 4
10 5
11 6
12 1
13 2
14 3
15 4
16 1
17 2
18 3
19 4
20 5
21 6
输出:
df
position
0 1
1 2
2 3
3 4
4 5
5 6
6 1
7 2
8 3
9 4
10 5
11 6
16 1
17 2
18 3
19 4
20 5
21 6