pandas数据框架的单元格引用,根据特定值进行过滤



我需要获取pandas数据框架中包含值== 1的所有区域的单元格引用(row#, col#)。

import pandas as pd
import numpy as np
df = pd.DataFrame({'x': [np.nan, 1, np.nan, np.nan, 1],
'y': [np.nan, np.nan, np.nan, np.nan, 1],
'z': [1, np.nan, 1, np.nan, np.nan]})

希望得到一个最终的数据框与两列:行&

row  col
0  1    1
1  4    1
2  4    2
3  0    3
4  2    3

您可以使用numpy.argwhere

这应该比使用forloop,df.stack等的所有解决方案快得多。请参阅下面的时间:

In [145]: import numpy as np
In [146]: res = pd.DataFrame(np.argwhere(df.notnull().values).tolist(), columns=['row', 'col'])
In [147]: res.col = res.col + 1
In [148]: res
Out[148]: 
row  col
0    0    3
1    1    1
2    2    3
3    4    1
4    4    2

时间:

np.argwhere:

In [149]: %timeit pd.DataFrame(np.argwhere(df.notnull().values).tolist(), columns=['row', 'col'])
437 µs ± 4.71 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

使用df.stack:

In [151]: %timeit pd.DataFrame(df[df.notna()].stack().index.tolist(),columns=['row','col'])
1.33 ms ± 5.55 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

您可以使用notna()获得布尔DataFrame返回,并使用stack()删除已转换为Falsenan。抓取index并转换为列表,以便您可以轻松地转换为DataFrame。

用正确的列名将其包装在pd.DataFrame()中可以得到所需的内容:

df.columns=[1,2,3]
pd.DataFrame(df[df.notna()].stack().index.tolist(),columns=['row','col'])

row  col
0    0    3
1    1    1
2    2    3
3    4    1
4    4    2

可以遍历行和列:

res_df = pd.DataFrame(columns=['row', 'col'])
for i in range(len(df)):
for j in range(len(df.columns)):
if df[df.columns[j]].iloc[i] == 1:
res_df = res_df.append({'row': i, 'col': j+1}, ignore_index=True)
print(res_df.sort_values(by='col').reset_index(drop=True))
row col
0   1   1
1   4   1
2   4   2
3   0   3
4   2   3

你可以试试:

import pandas as pd
import numpy as np
df = pd.DataFrame({'x': [np.nan, 1, np.nan, np.nan, 1],
'y': [np.nan, np.nan, np.nan, np.nan, 1],
'z': [1, np.nan, 1, np.nan, np.nan]})
list_indexes = []
for idx in range(len(df.columns)):
rows = df.index[df.iloc[:, idx] == 1].tolist()
for row in rows:
list_indexes.append((row, idx+1))
final = pd.DataFrame(list_indexes, columns=['row', 'column'])
print(final)

你可以这样做:

df.columns=list(range(1,len(df.columns)+1))
1    2   3
0   NaN NaN 1.0
1   1.0 NaN NaN
2   NaN NaN 1.0
3   NaN NaN NaN
4   1.0 1.0 NaN
new_df = df.stack().reset_index().rename(columns = {'level_0':'row', 'level_1':'col'})[['row', 'col']]
row  col
0    0    3
1    1    1
2    2    3
3    4    1
4    4    2

相关内容

  • 没有找到相关文章

最新更新