Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Stata/python中组合相似的行_Python_Pandas_Numpy_Stata_Networkx - Fatal编程技术网

在Stata/python中组合相似的行

在Stata/python中组合相似的行,python,pandas,numpy,stata,networkx,Python,Pandas,Numpy,Stata,Networkx,我正在为图表分析做一些数据准备,我的数据如下所示 country1 country2 pair volume USA CHN USA_CHN 10 CHN USA CHN_USA 5 AFG ALB AFG_ALB 2 ALB AFG ALB_AFG 5 import pandas as pd import io # load in your d

我正在为图表分析做一些数据准备,我的数据如下所示

country1   country2   pair      volume
USA         CHN       USA_CHN   10
CHN         USA       CHN_USA   5 
AFG         ALB       AFG_ALB   2
ALB         AFG       ALB_AFG   5
import pandas as pd
import io

# load in your data
s = """
country1   country2   pair      volume
USA        CHN        USA_CHN   10
CHN        USA        CHN_USA   5
AFG        ALB        AFG_ALB   2
ALB        AFG        ALB_AFG   5
"""
data = pd.read_table(io.BytesIO(s), sep='\s+')

# create your key (using frozenset instead of set, since frozenset is hashable)
key = data[['country1', 'country2']].apply(frozenset, 1)

# group by the key and aggregate using sum()
print(data.groupby(key).sum())
我想把它们结合起来,这样

country1   country2   pair      volume
USA         CHN       USA_CHN   15
AFG         ALB       AFG_ALB   7 
有没有一种简单的方法可以在Stata或python中实现?我曾尝试创建一个重复的数据帧,并将“对”重命名为country2\u country1,然后将它们合并,删除重复的卷,但这是一种令人毛骨悚然的方式:我想知道是否有更好的方式


如果有助于了解,我的数据格式是针对有向图的,我正在将其转换为无向图。

您的密钥必须由两个国家的集组成,以便它们在不考虑顺序的情况下进行相等的比较。在Python/Pandas中,这可以通过以下方式实现

country1   country2   pair      volume
USA         CHN       USA_CHN   10
CHN         USA       CHN_USA   5 
AFG         ALB       AFG_ALB   2
ALB         AFG       ALB_AFG   5
import pandas as pd
import io

# load in your data
s = """
country1   country2   pair      volume
USA        CHN        USA_CHN   10
CHN        USA        CHN_USA   5
AFG        ALB        AFG_ALB   2
ALB        AFG        ALB_AFG   5
"""
data = pd.read_table(io.BytesIO(s), sep='\s+')

# create your key (using frozenset instead of set, since frozenset is hashable)
key = data[['country1', 'country2']].apply(frozenset, 1)

# group by the key and aggregate using sum()
print(data.groupby(key).sum())
这导致

            volume
(CHN, USA)      15
(AFG, ALB)       7

这并不完全是您想要的,但您应该能够从这里将其设置为正确的形状。

这是一个自动对齐索引的解决方案

df1 = df.set_index(['country1'])
df2 = df.set_index(['country2'])
df1['volume'] += df2['volume']
df1.reset_index().query('country1 > country2')

  country1 country2     pair  volume
0      USA      CHN  USA_CHN      15
3      ALB      AFG  ALB_AFG       7
下面是一个基于@jean-françois fabre评论的解决方案

split_sorted = df.pair.str.split('_').map(sorted)
df_switch = pd.concat([split_sorted.str[0], 
                       split_sorted.str[1], 
                       df['volume']], axis=1, keys=['country1', 'country2', 'volume'])
df_switch.groupby(['country1', 'country2'], as_index=False, sort=False).sum()
输出

  country1 country2  volume
0      CHN      USA      15
1      AFG      ALB       7

在Stata中,你可以依靠这样一个事实:字母顺序给每一对赋予了一个不同的签名

clear 

input str3 (country1   country2)  volume
    USA         CHN         10 
    CHN         USA          5 
    AFG         ALB          2
    ALB         AFG          5
end 

gen first = cond(country1 < country2, country1, country2) 
gen second = cond(country1 < country2, country2, country1) 
collapse (sum) volume, by(first second) 

list 

     +-------------------------+
     | first   second   volume |
     |-------------------------|
  1. |   AFG      ALB        7 |
  2. |   CHN      USA       15 |
     +-------------------------+
清除
输入str3(国家1国家2)卷
美国CHN 10
中国美国5
AFG ALB 2
ALB AFG 5
结束
第一代=第二代(国家1<国家2,国家1,国家2)
第二代=秒(国家1<国家2,国家2,国家1)
折叠(总和)体积,按(第一秒)
列表
+-------------------------+
|第一卷第二卷|
|-------------------------|
1. |   AFG ALB 7|
2. |   中国美国15|
+-------------------------+
如果需要,您可以将与原始数据集合并

记录和讨论

注意:提供一个清晰的数据示例很有帮助。将其显示为
输入的代码
数据更有帮助

注意:正如尼克·考克斯(Nick Cox)在下面的评论,当国家数量众多时,这种解决方案有点疯狂。(对于200个国家/地区,您需要准确存储200位数字)

这里有一个使用纯Stata的简洁方法

我有效地将国家转换为二进制“旗帜”,制作了如下映射:

AFG  0001
ALB  0010
CHN  0100
USA  1000
这是通过对每个国家进行正常编号,然后计算
2^(国家/地区编号)
来实现的。当我们将这些二进制数相加时,结果是两个“标志”的组合。比如说,

AFG + CHN = 0101
CHN + AFG = 0101
请注意,国家的顺序现在没有任何区别

因此,我们现在可以愉快地添加标志,并根据结果对
进行求和

下面是完整的代码(大量注释,因此看起来比实际长得多!)

//将国家名称转换为数字,并存储结果
//名为“国家”的标签中的名称/编号映射
编码国家1,生成(来自国家)标签(国家)
//使用现有的
//已存在国家/地区的映射,并添加到
//不存在的现有映射
编码国家2,生成(至国家)标签(国家)
//添加这些数字,就像它们是二进制标志一样
//因此,CHN(3)+美国(4)成为:
// 010 +
// 100
// ---
// 110
//这使得添加字符串具有交换性和唯一性。这意味着
//新的变量不关心国家的方向
//它也不会被成对的国家加在一起搞混
//号码。
生成双边=2^从\u国家/地区+2^到\u国家/地区
//剩下的很简单。通过新的求和变量进行折叠
//(任意)从_国家中抽取最低的
//以及最高的to_国家
从_国家(最大)到_国家(双边)的塌陷(总和)体积(最小)
//告诉Stata,这些新的最小值和最大值国家仍然有相同的值
//标签:
来自_国家/地区“国家/地区”的标签值
将值标记为“国家/地区”

您可以使用
sorted\u pair=“\u0”).join(sorted(pair.split(“\u0”))创建一个“sorted”键
以便国家/地区始终处于相同的顺序;为了进一步帮助您,我们需要查看您的一些代码`实际上可以通过执行
df[['country1','country2']]=df[['country1','country2']]来简化第二种方法。应用(排序,1)
,然后
groupby(…)
将根据需要工作。非常好。没有考虑过应用程序,比如说200个不同的国家,您的
双边
最大值将是2的数量级,提高到该幂。您还需要无误地保存许多不同的值。因此,我不会像您默认的那样推荐使用
float
数据类型。(相反,如果您
将typedouble设置为默认值,这样就不会被咬到,这远远不是通用的。)我喜欢这里的巧妙技巧,但我认为这不是最好的方法。@NickCox fair comment。我曾想过使用列来存储每个国家的国旗,但这一切都有点烦人。你的编辑没有公平地捕捉事实。Stata可以处理这么大的数字;使用默认的[Repeation意为]变量类型是不可能的。斯塔塔的观点是程序员可能需要考虑变量应该如何保存。在这种情况下,我不理解你的反对意见。“远离通用”是什么意思?您可以
将type double
设置为自己的默认值(请参见
帮助生成
),但我在变量类型问题中看到的所有证据都是,很少有人注意到这一点,很少有人注意到这一点。