我正在为图形分析做一些数据准备,我的数据如下所示。
country1 country2 pair volume
USA CHN USA_CHN 10
CHN USA CHN_USA 5
AFG ALB AFG_ALB 2
ALB AFG ALB_AFG 5
我想把它们结合起来
country1 country2 pair volume
USA CHN USA_CHN 15
AFG ALB AFG_ALB 7
在Stata或python中,有一种简单的方法吗?我已经尝试制作一个重复的数据帧,并将'pair'重命名为country2_country1,然后合并它们,并删除重复的卷,但它是一种毛茸茸的方式来处理事情:我想知道是否有更好的方法。
如果有必要知道,我的数据格式是针对有向图,我将其转换为无向。
答案 0 :(得分:3)
您的密钥必须包含两个国家/地区的集,因此无论订单如何,它们都相等。在Python / Pandas中,这可以通过以下方式完成。
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
这不是你想要的,但你应该可以从这里得到正确的形状。
答案 1 :(得分:1)
这是一个让pandas自动对齐索引的解决方案
z
这是基于@ jean-françois-fabre评论的解决方案。
tree_delete
输出
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
答案 2 :(得分:1)
在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 |
+-------------------------+
如果愿意,您可以merge
返回原始数据集。
记录并讨论here
注意:提供明确的数据示例很有帮助。将其作为input
数据的代码呈现更有帮助。
答案 3 :(得分:0)
注意:正如Nick Cox在下面评论的那样,当国家数量很大时,这个解决方案会有点疯狂。 (有200个国家/地区,您需要准确存储200位数字)
这是使用纯Stata完成它的一种巧妙方法。
我有效地将国家/地区转换为二进制“标志”,类似于以下映射:
AFG 0001
ALB 0010
CHN 0100
USA 1000
这是通过将每个国家编号为正常,然后计算2^(country_number)
来实现的。然后,当我们添加这些二进制数时,结果是两个“标志”的组合。例如,
AFG + CHN = 0101
CHN + AFG = 0101
请注意,现在各国的订单顺序没有任何区别!
因此,我们现在可以愉快地添加标记和结果collapse
,并在volume
之后总结。
这是完整的代码(评论很多,所以它看起来比它长得多!)
// Convert country names into numbers, storing the resulting
// name/number mapping in a label called "countries"
encode country1, generate(from_country) label(countries)
// Do it again for the other country, using the existing
// mappings where the countries already exist, and adding to the
// existing mapping where they don't
encode country2, generate(to_country) label(countries)
// Add these numbers as if they were binary flags
// Thus CHN (3) + USA (4) becomes:
// 010 +
// 100
// ---
// 110
// This makes adding strings commutative and unique. This means that
// the new variable doesn't care which way round the countries are
// nor can it get confused by pairs of countries adding up to the same
// number.
generate bilateral = 2^from_country + 2^to_country
// The rest is easy. Collapse by the new summed variable
// taking (arbitrarily) the lowest of the from_countries
// and the highest of the to_countries
collapse (sum) volume (min) from_country (max) to_country, by(bilateral)
// Tell Stata that these new min and max countries still have the same
// label:
label values from_country "countries"
label values to_country "countries"