【问题标题】:Split a single excel cell content into different cells using Python or Excel vba使用 Python 或 Excel vba 将单个 excel 单元格内容拆分为不同的单元格
【发布时间】:2019-06-08 15:43:06
【问题描述】:

我有一个格式如下所示的数据,可以使用下面给出的 Python 代码生成该数据

df = pd.DataFrame({'Person_id':[1,2,3,4],
'Values':['father:1.Yes 2.No 3.Do not Know','Mother:1.Yes 2.No 3.Do not 
 Know','sons:1.Yes 2.No 3.Do not Know','daughter:1.Yes 2.No 3.Do not Know'],
   'Ethnicity':['dffather','dfmother','dfson','dfdaughter']})

我想做的是根据单元格中可用值的数量将“值”单元格内容拆分为 3 个单独的行/ n 个单独的行。在这种情况下,我们有 3 个选项(1.是、2.否和 3.不知道)。我不希望保留父亲、母亲、儿子等文本。我只希望有选项

我怎样才能让我的输出如下所示

请注意,选项和值可能实时不同。我展示的是一个示例,在答案选项方面不存在任何模式。

【问题讨论】:

  • 酷。一个任务。你的任务?你做了什么来解决它?您的解决方案的具体问题在哪里?请向我们展示您的 [mce]。
  • 我做了一些 Pandas 工作,并将数据作为 Variant 数组返回到 VBA(准备粘贴到单元格中)。 exceldevelopmentplatform.blogspot.com/2018/06/… 这是我的博客,我使用 Python 网关类模式。 toList() 是将 Python 数据结构转换为 VBA 可使用的东西的关键
  • 将在此处尝试答案并尽快更新解决方案。
  • 下面提供的两个答案都运行良好。我正在标记 Python 方法,因为它对于像我这样的初学者来说很容易理解。尽管如此,Excel VBA 也是一种有效且有效的解决方案。对两个答案都投了赞成票

标签: python excel python-3.x vba pandas


【解决方案1】:

一种方式可以是(熊猫):

s=df.Values.str.findall('(\D+)').str[1:]
m=(df.reindex(df.index.repeat(s.str.len()))
   .assign(new_Value=np.concatenate(s.values)).drop('Values',1))
m.new_Value=m.groupby('Person_id').cumcount().add(1).astype(str)+m.new_Value
print(m)

   Person_id   Ethnicity      new_Value
0          1    dffather         1.Yes 
0          1    dffather          2.No 
0          1    dffather  3.Do not Know
1          2    dfmother         1.Yes 
1          2    dfmother          2.No 
1          2    dfmother  3.Do not Know
2          3       dfson         1.Yes 
2          3       dfson          2.No 
2          3       dfson  3.Do not Know
3          4  dfdaughter         1.Yes 
3          4  dfdaughter          2.No 
3          4  dfdaughter  3.Do not Know

【讨论】:

  • 你好@anky_91 - 我确实尝试过你的答案。它工作正常。但是,为了获得预期的输出,我添加了以下两行,因为我不希望重复 Ethnicity 和 Person_id 列中的值。虽然我这样做了,但觉得这是一个漫长/回合的方法。这是我的附加代码,使其 NA 用于重复值 "m['Ethnicity']=m[('Ethnicity')].mask(~m['new_Value'].str.startswith('1.') ) m['Person_id']=m[('Person_id')].mask(~m['new_Value'].str.startswith('1.'))"。
  • @AVLES 我猜你需要m.loc[m.duplicated(['Person_id','Ethnicity']),['Person_id','Ethnicity']]='' 然后打印 m 来检查。 :)
  • 在上面的例子中,如果我想根据它们的源值对输入进行排序,你能告诉我怎么做吗?例如:1:是,2:否,777:不适用,999:不知道。如您所见,它不是 3 和 4,而是 777 和 999。我想保留这些值
  • @AVLES 嗯.. 我认为这需要不同的(复杂的)方法。既然这个问题已经回答了,我建议你发布一个新问题。
  • 谢谢@anky_91。这是链接stackoverflow.com/questions/56536954/…
【解决方案2】:

VBA 的角度来看,这是您可以做到的一种方式:

Option Explicit

Sub splitVals()

Dim ws As Worksheet: Set ws = ActiveWorkbook.Sheets("Sheet Name")
Dim arrData As Variant, arrValues() As String
Dim arrTmp() As String: ReDim arrTmp(1 To 2, 1 To 1)
Dim arrFinal() As String

Dim lrow As Long: lrow = ws.Cells(Rows.Count, 1).End(xlUp).Row
Dim R As Long, C As Long, X As Long, Z As Long

arrData = ws.Range("A1:C" & lrow)

For R = LBound(arrData) + 1 To UBound(arrData)
    arrData(R, 2) = Replace("df" & arrData(R, 2), arrData(R, 3) & ":", "")
    arrValues = Split(arrData(R, 2), ".")
    For X = LBound(arrValues) To UBound(arrValues)
        If X + 1 = UBound(arrValues) Then
            arrValues(X) = X + 1 & "." & arrValues(X + 1)
            ReDim Preserve arrValues(X)
            Exit For
        Else
            arrValues(X) = X + 1 & "." & Left(arrValues(X + 1), Len(arrValues(X + 1)) - 2)
        End If
    Next X

    For X = LBound(arrValues) To UBound(arrValues)
        Z = Z + 1
        ReDim Preserve arrTmp(1 To 2, 1 To Z)
        If X = 0 Then arrTmp(1, Z) = R - 1
        arrTmp(2, Z) = arrValues(X)
    Next X
Next R

ReDim arrFinal(LBound(arrTmp, 2) To UBound(arrTmp, 2), LBound(arrTmp) To UBound(arrTmp))
For R = LBound(arrFinal) To UBound(arrFinal)
    For C = LBound(arrFinal, 2) To UBound(arrFinal, 2)
        arrFinal(R, C) = arrTmp(C, R)
    Next C
Next R

With ws.Range("E1")
    .Resize(UBound(arrFinal), UBound(arrFinal, 2)) = arrFinal
End With

End Sub

结果:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多