我有一个如下所示的数据框df
:
key_1, key_2, country
12, a, US
12, a, US
12, b, US
12, c, NZ
23, d, PE
23, e, PE
23, e, PE
31, f, RO
31, f, RO
42, g, VI
我对满足以下条件的2个数据帧(请为每个数据帧提供一个过程)感兴趣:
1st-给予key_1,有一个唯一的key_2 AND
个唯一的国家/地区。例如。
23, d, PE
23, e, PE
第二 - 给予一个key_1,有多个唯一的key_2 AND
多个唯一的国家/地区。例如。
12, a, US
12, b, US
12, c, NZ
在这两种情况下,生成的数据框都应具有唯一的行。
现在已经读了一段时间的其他问题,但我最接近的是:
result = df.groupby("key_1")["key_2"].apply(pd.value_counts).count(level=0)
这有助于我找到哪些行具有多个唯一的" key_2
每key_1
" (我的大部分数据框都是由一个唯一的key_2和每个key_1行的国家/地区组成,无论重复如何),但我还远远不能满足我的要求。
非常感谢您提前! (对不起问题标题,但我不知道该怎么称呼它)
答案 0 :(得分:1)
经过几个小时的挖掘,我终于成功了。任何有更好解决方案的人都欢迎回答!
我在我的真实数据框架上尝试了以下代码,但它确实有效。
正如@Alexander正确指出的那样,"您所需的两个数据帧都建立在同一组数据上:对于给定的key_1具有多个key_2的行_"
因此,对于给定key_1的具有多个唯一key_2的行,我首先进行子集化。然后我将它分为2:一个用于给一个key_1的唯一国家,另一个用于超过2个国家给一个key_1。
# more than one unique key_2 per key_1
subset_k2= df.groupby(['key_1'])['key_2'].nunique().reset_index()
subset_k2= subset_gb[subset_gb[key_2] > 1]
subset_all= df[df["key_1"].isin(subset_k2["key_1"].tolist())]
# more than one unique country per key_1
subset_ct= df.groupby(['key_1'])['country'].nunique().reset_index()
subset_ct= subset_ct[subset_ct['country'] > 1]
# Results that fulfill condition 2 from my question:
result_2 = subset_all[subset_all["key_1"].isin(subset_ct["key_1"].tolist())].drop_duplicates()
# Results that fulfill condition 1 from my question:
result_1 = subset_all[~subset_all["key_1"].isin(subset_ct["key_1"].tolist())].drop_duplicates()
答案 1 :(得分:0)
您可以使用get_groups和drop_duplicates:
In [11]: g = df.groupby("key_1")
In [12]: g.get_group(12).drop_duplicates()
Out[12]:
key_1 key_2 country
0 12 a US
2 12 b US
3 12 c NZ
In [13]: g.get_group(23).drop_duplicates()
Out[13]:
key_1 key_2 country
4 23 d PE
5 23 e PE
答案 2 :(得分:0)
您所需的两个数据框都建立在同一组数据上:给定key_2
的行数超过key_1
。
首先,我们会在key_1
上进行分组并计算key_2
个值。我们创建了一个名为keys
的列表,其中key_2
计数大于一。
然后使用这些键过滤原始数据帧。
接下来,我们会将国家/地区计数(在key_1
和key_2
上分组)合并到数据框中。
最后,我们根据它的country_count
值(即等于1且大于1)来拆分此数据帧。
from collections import Counter
# Create sample data.
df = pd.DataFrame({'key_1': [12,12,12,12,23,23,23,31,31,42],
'key_2': list('aabcdeeffg'),
'country': ['US', 'US', 'US', 'NZ', 'PE', 'PE', 'PE', 'RO', 'RO', 'VI']})
# Get list of key pairs where there are more than one `key_2` for a given `key_1`
gb1 = df.groupby(['key_1', 'key_2']).key_2.count()
keys = gb1[gb1 > 1].index.tolist()
# Filter the dataframe for the correct keys.
idx = [n for n, pair in enumerate(zip(df.key_1, df.key_2)) if pair in keys]
df_temp = df.ix[idx]
# Get the country count for each `key_`1 / `key_2' pair.
gb1 = df_temp.groupby('key_1').key_2.apply(Counter)
df_temp = pd.DataFrame(gb1.reset_index().values, columns=['key_1', 'key_2', 'country_count'])
df_temp = df.merge(df_temp, on=['key_1', 'key_2'])
# More than one unique `key_2` for a given `key_1` and only one country.
df1 = df_temp.loc[df_temp.country_count == 1, ['key_1', 'key_2', 'country']]
# More than one unique `key_2` for a given `key_1` and more than one country.
df2 = df_temp.loc[df_temp.country_count > 1, ['key_1', 'key_2', 'country']]