假设我有一个如下数据框。我想要的是,如果列a,b,c之间的数字出现最多,那么它应输出该数字,或者如果所有三个数字不同,则取a的数字。例如,在第一行中,1出现在1和5中最多,然后d中的输出为1.但在第二行中,列a,b,c的所有三个数字11,2,7都不同,输出是列的值a(11),所以d中的输出是11
list a b c
1 1 5 1
11 11 2 7
0 0 0 0
9 5 9 5
8 8 2 7
预期输出
list a b c d
1 1 5 1 1
11 11 2 7 11
0 0 0 0 0
9 5 9 5 5
8 8 2 7 8
答案 0 :(得分:1)
scipy计算模式,但我很惊讶,不要在numpy中找到它。
import pandas as pd
import numpy as np
from scipy import stats
df = pd.DataFrame([[1, 1, 5, 1],
[11, 11, 2, 7],
[0, 0, 0, 0],
[9, 5, 9, 5],
[8, 8, 2, 7]],
columns=['list', 'a', 'b', 'c'])
df['d'], df['count'] = stats.mode(df[['a', 'b', 'c']].values, axis=1)
df.loc[df['count'] == 1, 'd'] = df['a']
df = df.drop('count', 1)
答案 1 :(得分:1)
您可以使用value_counts
df.iloc[:,1:].apply(lambda x : x.value_counts().index[0] if x.value_counts().iloc[0]>1 else x['a'] ,1)
Out[1046]:
0 1
1 11
2 0
3 5
4 8
dtype: int64
答案 2 :(得分:1)
这是我的bincount
解决方案
数据强>
请注意,这与OP的不同之处在于指出它按预期工作。
list a b c
0 1 5 1 1
1 11 11 2 7
2 0 0 0 0
3 9 5 9 5
4 8 8 2 7
解决方案
v = df.values[:, 1:]
f, u = pd.factorize([(i, e) for i, row in enumerate(v) for e in row])
counts = np.bincount(f)[f].reshape(v.shape)
x = (counts == counts.max(1, keepdims=1)).argmax(1)
y = np.arange(v.shape[0])
df.assign(d=v[y, x])
list a b c d
0 1 5 1 1 1
1 11 11 2 7 11
2 0 0 0 0 0
3 9 5 9 5 5
4 8 8 2 7 8
详情
获取我们想要的值的numpy数组。
v = df.values[:, 1:]
使用enumerate
和理解来创建元组列表。每个行值将与其他行不同,因为我在每个行的元组的第一个位置放置一个标识符。即枚举值。然后我将这些传递给Pandas的factorize
函数,以便放入Numpy的bincount
。
f, u = pd.factorize([(i, e) for i, row in enumerate(v) for e in row])
现在我在bincount
上使用f
并使用f
对其进行切片以获得相同大小的数组,但现在已填充计数值。
counts = np.bincount(f)[f].reshape(v.shape)
我找到了最大值并对原始数组进行切片以获得那些值所在的位置。
x = (counts == counts.max(1, keepdims=1)).argmax(1)
y = np.arange(v.shape[0])
请注意,如果所有值都相同或者有多种模式,argmax
将选择第一个。如果全部相同,则为a
列。
df.assign(d=v[y, x])
答案 3 :(得分:0)
正如@piRSquared建议的那样,我们可以在pandas中使用mode
函数。
df["d"] = np.where(df.apply(lambda x: x.nunique() == 3, 1),
df["a"],
df.mode(1).loc[:,0])
另一种方法(为了好玩)
df["d"] = np.where(df['b'] == df['c'], df['b'], df['a'])
伪代码解释
if b == c:
choose b because b and c are both the mode
else: # when b != c
if a == c or a == b:
choose a because a is the mode
else: # a != b != c
choose a because all are different