【问题标题】:Move column values to values with True/False将列值移动到 True/False 值
【发布时间】:2020-06-09 16:00:28
【问题描述】:

我有一个类似的数据集:

 data = {'lat': [0.15, 0.15, 0.15, 0.15, 0.25, 0.25, 0.48, 0.48, 0.48, 0.48],
        'lon': [0.87, 0.87, 0.87, 0.87, 0.12, 0.12, 0.59, 0.59, 0.59, 0.59],
        'animal': ['dog', 'cat', 'rat', 'rat', 'cat', 'rat', 'cat', 'dog', 'dog', 'rat'],
        'category': ['A', 'C', 'B', 'C', 'B', 'B', 'C', 'A', 'C', 'C']}
mdf = pd.DataFrame(data)

mdf
Out[460]: 
    lat   lon animal category
0  0.15  0.87    dog        A
1  0.15  0.87    cat        C
2  0.15  0.87    rat        B
3  0.15  0.87    rat        C
4  0.25  0.12    cat        B
5  0.25  0.12    rat        B
6  0.48  0.59    cat        C
7  0.48  0.59    dog        A
8  0.48  0.59    dog        C
9  0.48  0.59    rat        C

我想使用 'animal'、'lat' 和 'lon' 作为某种索引来获得这样的结果:

      lat   lon animal     A      B      C
0    0.15  0.87    dog True   False  False
1    0.15  0.87    cat False  False  True
2    0.15  0.87    rat False  True   True
4    0.25  0.12    cat False  True   False
5    0.25  0.12    rat False  True   False
6    0.48  0.59    cat False  False  True
7    0.48  0.59    dog True   False  True
9    0.48  0.59    rat False  False  True

我真的不在乎它是真/假、1/0 等等,只要我能看到“lat”、“long”和“animal”的每个组合都有哪些类别。

我一直在尝试几种选择,但均未成功:pivot、pivot_table、groupby、stack/unstack...但似乎没有一个能满足我的需求。

我剩下的唯一选择是遍历不同的“纬度”、“经度”、“动物”备选方案,并检查每个“类别”是否出现。

也许这可以通过将'lat'、'lon'、'animal'定义为索引并以某种方式“unmelting”来以某种方式完成

有什么建议吗?

谢谢。


编辑:我无法在 cmets 中添加新行,而且我不知道如何联系关闭帖子的人,所以让我在这里补充一些解释。抱歉给您带来的困扰。

Quang,感谢您引用不同的线程。但是,我不确定它是否对我有帮助。

我可以这样做:

pd.get_dummies(mdf['category'], prefix='', prefix_sep='')

但是我得到了最初的 10 行,而不是我瞄准的表格。

要使用 get_dummies 获得有用的东西,我必须这样做:

mdf = mdf.join(pd.get_dummies(mdf['category'], prefix='', prefix_sep=''))
mdf[['A', 'B', 'C']] = mdf.groupby(['lat', 'lon', 'animal'])[['A', 'B', 'C']].transform('sum')
mdf.drop_duplicates(subset=['lat', 'lon', 'animal'], inplace=True)
d = {1: True,
     0: False}
mdf[['A', 'B', 'C']] = mdf[['A', 'B', 'C']].replace(d)
mdf.drop('category',
        axis=1,
        inplace=True)

但这似乎过于复杂,我觉得必须有更好的方法......

我也想过这个:

mdf['value'] = [True] * 10
mdf = mdf.set_index(['lat', 'lon', 'animal', 'category'])
mdf = mdf.unstack(fill_value=False)
mdf = mdf.reset_index()
mdf.columns = ['lat', 'lon', 'animal', 'A', 'B', 'C']

但同样,通过玩索引来欺骗系统似乎太不合 Python 了...

肯定有更好的办法!

谢谢。

【问题讨论】:

    标签: python pandas data-manipulation


    【解决方案1】:

    我的原始索引值无关紧要,您可以使用get_dummiesABC 列连接到原始数据帧,然后按经纬度和动物分组并对布尔列求和:

    categs = np.sort(mdf['category'].unique())
    
    resul = pd.concat([mdf, pd.get_dummies(mdf['category']).astype(bool)], axis=1
                      ).groupby(['lat', 'lon', 'animal'])[categs].sum().reset_index()
    

    它给出:

        lat   lon animal      A      B      C
    0  0.15  0.87    cat  False  False   True
    1  0.15  0.87    dog   True  False  False
    2  0.15  0.87    rat  False   True   True
    3  0.25  0.12    cat  False   True  False
    4  0.25  0.12    rat  False   True  False
    5  0.48  0.59    cat  False  False   True
    6  0.48  0.59    dog   True  False   True
    7  0.48  0.59    rat  False  False   True
    

    【讨论】:

    • 谢谢@serge-ballesta,我真的很喜欢。它在概念上与我的第一个建议相似,但更加优雅和精简。我很难理解这部分groupby(['lat', 'lon', 'animal'])[categs] 为什么需要[categs]?选择行是否是最佳实践,例如.loc()?看来.transform() 会有所不同,但.sum() 不会。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2021-12-25
    • 2018-02-18
    • 1970-01-01
    • 2013-11-09
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2020-08-01
    相关资源
    最近更新 更多