我有一个像
这样的数据帧 Sou Des
1 3
1 4
2 3
2 4
3 1
3 2
4 1
4 2
我需要为0到1之间的每一对分配随机值,但必须为类似的对分配相同的随机值,如“1-3”,“3-1”和其他对。我期待像
这样的结果数据帧 Sou Des Val
1 3 0.1
1 4 0.6
2 3 0.9
2 4 0.5
3 1 0.1
3 2 0.9
4 1 0.6
4 2 0.5
如何在python pandas中为“A-B”和“B-A”分配相同的随机值类似的对。
答案 0 :(得分:6)
让我们首先创建一个按axis=1
帮助DF排序:
In [304]: x = pd.DataFrame(np.sort(df, axis=1), df.index, df.columns)
In [305]: x
Out[305]:
Sou Des
0 1 3
1 1 4
2 2 3
3 2 4
4 1 3
5 2 3
6 1 4
7 2 4
现在我们可以按列进行分组:
In [306]: df['Val'] = (x.assign(c=1)
.groupby(x.columns.tolist())
.transform(lambda x: np.random.rand(1)))
In [307]: df
Out[307]:
Sou Des Val
0 1 3 0.989035
1 1 4 0.918397
2 2 3 0.463653
3 2 4 0.313669
4 3 1 0.989035
5 3 2 0.463653
6 4 1 0.918397
7 4 2 0.313669
答案 1 :(得分:2)
这是新方式
s=pd.crosstab(df.Sou,df.Des)
b = np.random.random_integers(-2000,2000,size=(len(s),len(s)))
sy = (b + b.T)/2
s.mul(sy).replace(0,np.nan).stack().reset_index()
Out[292]:
Sou Des 0
0 1 3 -60.0
1 1 4 -867.0
2 2 3 269.0
3 2 4 1152.0
4 3 1 -60.0
5 3 2 269.0
6 4 1 -867.0
7 4 2 1152.0
答案 2 :(得分:0)
这里的诀窍是远离数据框做一些工作。您可以将其分解为三个步骤:
(a,b)
(b,a)
和df
具有相同的值假设您的数据框名为a <= b
,我们可以列出所有订购的对,以便(a,b)
。我认为这比试图跟踪(b,a)
和pairs = set([(a,b) if a <= b else (b,a)
for a, b in df.itertuples(index=False,name=None))
更容易。
pair_dict
这很简单,可以为这些对中的每一对分配一个随机数并将其存储在字典中,因此我将其留给您。称之为df['Val'] = df.apply(<some function>, axis=1)
。
现在,我们只需要查找值。我们最终想写
pair_dict
我们的函数在def func(row):
if row['Sou'] <= row['Des']:
key = (row['Sou'], row['Des'])
else:
key = (row['Des'], row['Sou'])
return pair_dict[key]
中查找适当的值。
不要试图把它塞进一个lambda(尽管我们可以),让我们单独写一下。
views
--home(subfolder)
--beranda(subfolder)
--refresh.blade.php
--layouts(subfolder)
--master.blade.php
答案 3 :(得分:0)
如果你可以使用来自hash()方法的&#34; random&#34; 值,你可以使用frozenset()实现
df = pd.DataFrame([[1,1,2,2,3,3,4,4],[3,4,3,4,1,2,1,2]]).T
df.columns = ['Sou','Des']
df['Val']= df.apply(lambda x: hash(frozenset([x["Sou"],x["Des"]])),axis=1)
print df
给出:
Sou Des Val
0 1 3 1580307032
1 1 4 -1736016661
2 2 3 741508915
3 2 4 -1930135584
4 3 1 1580307032
5 3 2 741508915
6 4 1 -1736016661
7 4 2 -1930135584