如何在DataFrame中连续找到第n个最小数字,并将该值作为新列中的条目添加(因为我最终想要导出数据)。 Example Data
答案 0 :(得分:4)
设置
np.random.seed([3,14159])
df = pd.DataFrame(np.random.randint(10, size=(4, 5)), columns=list('ABCDE'))
A B C D E
0 4 8 1 1 9
1 2 8 1 4 2
2 8 2 8 4 9
3 4 3 4 1 5
在以下所有解决方案中,我假设n = 3
解决方案1
功能prt
低于
使用np.partition
将最小的部分放在分区的左侧,将最大的部分放在右侧。然后全部向左走,找到最大值
df.assign(nth=np.partition(df.values, 3, axis=1)[:, :3].max(1))
A B C D E nth
0 4 8 1 1 9 4
1 2 8 1 4 2 2
2 8 2 8 4 9 8
3 4 3 4 1 5 4
解决方案2
功能srt
低于
np.sort
df.assign(nth=np.sort(df.values, axis=1)[:, 2])
A B C D E nth
0 4 8 1 1 9 4
1 2 8 1 4 2 2
2 8 2 8 4 9 8
3 4 3 4 1 5 4
解决方案3
功能rnk
低于
使用pd.DataFrame.rank
简化为浮动的简洁版
df.assign(nth=df.where(df.rank(1, method='first').eq(3)).stack().values)
A B C D E nth
0 4 8 1 1 9 4.0
1 2 8 1 4 2 2.0
2 8 2 8 4 9 8.0
3 4 3 4 1 5 4.0
解决方案4
功能whr
低于
使用np.where
和pd.DataFrame.rank
i, j = np.where(df.rank(1, method='first') == 3)
df.assign(nth=df.values[i, j])
A B C D E nth
0 4 8 1 1 9 4
1 2 8 1 4 2 2
2 8 2 8 4 9 8
3 4 3 4 1 5 4
<强>时序强>
请注意,srt
最快但与prt
相当,但对于较大数量的列,prt
的效率更高效。
res.plot(loglog=True)
prt = lambda df, n: df.assign(nth=np.partition(df.values, n, axis=1)[:, :n].max(1))
srt = lambda df, n: df.assign(nth=np.sort(df.values, axis=1)[:, n - 1])
rnk = lambda df, n: df.assign(nth=df.where(df.rank(1, method='first').eq(n)).stack().values)
def whr(df, n):
i, j = np.where(df.rank(1, method='first').values == n)
return df.assign(nth=df.values[i, j])
res = pd.DataFrame(
index=[10, 30, 100, 300, 1000, 3000, 10000],
columns='prt srt rnk whr'.split(),
dtype=float
)
for i in res.index:
num_rows = int(np.log(i))
d = pd.DataFrame(np.random.rand(num_rows, i))
for j in res.columns:
stmt = '{}(d, 3)'.format(j)
setp = 'from __main__ import d, {}'.format(j)
res.at[i, j] = timeit(stmt, setp, number=100)
答案 1 :(得分:1)
以下是查找列表中第n个最小项目的方法:
def find_nth_in_list(list, n):
return sorted(list)[n-1]
用法:
list =[10,5,7,9,8,4,6,2,1,3]
print(find_nth_in_list(list, 2))
输出:
2
您可以将行项目作为列表提供给此功能。
修改强>
您可以找到具有此功能的行:
#Returns all rows as a list
def find_rows(df):
rows=[]
for row in df.iterrows():
index, data = row
rows.append(data.tolist())
return rows
使用示例:
rows = find_rows(df) #all rows as a list
smallest_3th = find_nth_in_list(rows[2], 3) #3rd row, 3rd smallest item
答案 2 :(得分:1)
您可以按照以下方式执行此操作:
df.assign(nth=df.apply(lambda x: np.partition(x, nth)[nth], axis='columns'))
示例:
In[72]: df = pd.DataFrame(np.random.rand(3, 3), index=list('abc'), columns=[1, 2, 3])
In[73]: df
Out[73]:
1 2 3
a 0.436730 0.653242 0.843014
b 0.643496 0.854859 0.531652
c 0.831672 0.575336 0.517944
In[74]: df.assign(nth=df.apply(lambda x: np.partition(x, 1)[1], axis='columns'))
Out[74]:
1 2 3 nth
a 0.436730 0.653242 0.843014 0.653242
b 0.643496 0.854859 0.531652 0.643496
c 0.831672 0.575336 0.517944 0.575336
答案 3 :(得分:0)
生成一些随机数据
dd=pd.DataFrame(data=np.random.rand(7,3))
使用numpy找到每行的最小值
dd['minPerRow']=dd.apply(np.min,axis=1)
导出结果
dd['minPerRow'].to_csv('file.csv')