【问题标题】:Creating array of strings创建字符串数组
【发布时间】:2017-07-30 22:23:15
【问题描述】:

我有一个不同类型的标志数组:

Data Type1 Type2 Type3
12   1     0     0
14   0     1     0
3    0     1     0
45   0     0     1

我想创建以下数组:

Data TypeName
12   Type1   
14   Type2   
3    Type2   
45   Type3   

我尝试创建一个空的类型字符串数组:

import numpy as np
z1 = np.empty(4, np.string_)
z1[np.where(Type1=1)] = 'Type1'

但这似乎并没有给我想要的结果。

编辑: 我可以使用熊猫数据框,每行只有一种类型,Type1,Type2,Type3

编辑2: Data Type1 Type2 Type3 是 pandas 数据框中的列名,但我使用的是带有隐式名称的 numpy 数组,正如我在上面的示例中所指出的那样。

【问题讨论】:

  • 输入是熊猫数据框吗?从第二列开始,每一行是否总是有一个 1
  • 你能告诉我们如何创建这样一个输入数组吗?

标签: python pandas numpy


【解决方案1】:

这是一种滥用的方法,即我们从Type1 列和idxmax() 开始每行只有一个1,以使每行唯一出现它 -

pd.concat((df.Data, df.iloc[:,1:].idxmax(1)),axis=1)

示例运行 -

In [42]: df
Out[42]: 
   Data  Type1  Type2  Type3
0    12      1      0      0
1    14      0      1      0
2     3      0      1      0
3    45      0      0      1

In [43]: pd.concat((df.Data, df.iloc[:,1:].idxmax(1)),axis=1)
Out[43]: 
   Data      0
0    12  Type1
1    14  Type2
2     3  Type2
3    45  Type3

【讨论】:

  • 我真的很喜欢这个解决方案。其实你不需要pd.concat - df.set_index('Data').idxmax(1).reset_index(name='TypeName')
【解决方案2】:

更新:这里是a brilliant @Divakar's idea 使用DataFrame.idxmax(1) 方法和使用set_index()reset_index() 以摆脱pd.concat() 的混合:

In [142]: df.set_index('Data').idxmax(1).reset_index(name='TypeName')
Out[142]:
   Data TypeName
0    12    Type1
1    14    Type2
2     3    Type2
3    45    Type3

旧答案:

你可以这样做(熊猫解决方案):

In [132]: df.set_index('Data') \
            .stack() \
            .reset_index(name='val') \
            .query("val == 1") \
            .drop('val', 1)
Out[132]:
    Data level_1
0     12   Type1
4     14   Type2
7      3   Type2
11    45   Type3

【讨论】:

  • 您应该将您的建议添加到您的帖子中。我认为在你的帖子中值得一提!
  • @Divakar,但这里的主要思想是使用.idxmax(1) - 你是第一个...... ;)
  • 链接到我的帖子!但是一定要加! :)
【解决方案3】:

一种方法是通过

df.apply(lambda row: 'Type1' if row.Type1 else 'Type2' if row.Type2 else 'Type3', axis=1)

例如:

In [6]: df
Out[6]: 
   Data  Type1  Type2  Type3
0    12      1      0      0
1    14      0      1      0
2     3      0      1      0
3    45      0      0      1

In [7]: df['TypeName'] = df.apply(lambda row: 'Type1' if row.Type1 else 'Type2' if row.Type2 else 'Type3', axis=1)

In [9]: df.drop(['Type1', 'Type2', 'Type3'], axis=1)
Out[9]: 
   Data TypeName
0    12    Type1
1    14    Type2
2     3    Type2
3    45    Type3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-10
    • 2013-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多