【问题标题】:IPython + pandas oneliner not workingIPython + pandas oneliner 不工作
【发布时间】:2013-10-24 13:35:03
【问题描述】:

我正在尝试在 IPython 上做一个单行器,但我得到了SyntaxError: invalid syntax。代码如下:

 for zzz in ddd.index: zzz1 = zzz.split('///'); zzz3 = [zzz2.strip() for zzz2 in zzz1 if len(zzz1) > 1]; for zzz4 in zzz3: ddd.ix[zzz4]['Class'] = ddd.ix[zzz]['Class']; del ddd.ix[zzz]

我可以这样解释: 对于 DataFrame ddd 索引上的每个值,我使用 /// 作为分隔符对其进行拆分。然后,如果返回多个值,我为每个值创建一行并删除原始行。 例如,我有:

             Class
lal          1
eri /// iii  2
aks          3

我要获得

             Class
lal          1
eri          2
iii          2
aks          3

第一列(`lal', 'eri', ... )是数据帧的索引。

我怎样才能做到这一点?我已经搜索了文档,但我没有弄清楚如何去做。

谢谢

【问题讨论】:

  • 这个重复:stackoverflow.com/questions/19552248/…,使用ddd.ix[zzz4,'Class`] = ddd.ix[zzz,'Class']
  • 它不起作用..也许它不允许使用这种语法在一行中使用两个 for?
  • 出于好奇:为什么对这一行感兴趣?你有某种反垂直偏见吗?这在 Python 中会是个问题,因为编写好的代码涉及到 if/elif/elsetry/except,你不能把它们放在一行。
  • 大声笑,我的错。我也是,我只是在玩 IPython 以逐步创建管道,只是为了看看如何做某事..

标签: python pandas ipython dataframe


【解决方案1】:

不知道你想在这里做什么。

In [13]: df
Out[13]: 
             A  B
0          lal  1
1  eri /// iii  2
2          aks  3

这是一个非常长的表达式来做到这一点。好消息是这会很快。

In [56]: split = df['A'].str.split('\s+\/\/\/\s+').apply(Series)

In [57]: split
Out[57]: 
     0    1
0  lal  NaN
1  eri  iii
2  aks  NaN

In [58]: indexed = split.unstack().dropna()

In [59]: indexed
Out[59]: 
0  0    lal
   1    eri
   2    aks
1  1    iii
dtype: object

 In [61]: grouped = indexed.groupby(level=1).apply(
           lambda x: Series(x.values,index=list(x.index.get_level_values(1))))

In [62]: grouped
Out[62]: 
0  0    lal
1  1    eri
   1    iii
2  2    aks
dtype: object

In [63]: grouped.reset_index().set_index('level_1')
Out[63]: 
         level_0    0
level_1              
0              0  lal
1              1  eri
1              1  iii
2              2  aks

【讨论】:

  • 我认为 OP 在 pd.DataFrame({"Index": ["lal", "eri", "iii", "aks"], "Class": [1,2,2,3]}) 之后,虽然我不知道 Index 是作为列还是索引。
  • @DSM 你是对的,Index 是索引。我会更新问题
【解决方案2】:

这里有一个与@Jeff 截然相反的版本:非常,但我认为很清楚。

index_pairs = [(ind, subind.strip()) for ind in df.index for subind in ind.split("///")]
old_i, new_i = zip(*index_pairs)
df2 = df.ix[list(old_i)]
df2.index = new_i

请注意,假设原始索引是唯一的


从我们的框架开始:

>>> df
             Class
lal              1
eri /// iii      2
aks              3

根据需要创建一个将原始索引与尽可能多的新子索引连接起来的对列表:

>>> index_pairs = [(ind, subind.strip()) for ind in df.index for subind in ind.split("///")]
>>> index_pairs
[('lal', 'lal'), ('eri /// iii', 'eri'), ('eri /// iii', 'iii'), ('aks', 'aks')]

转置:

>>> old_i, new_i = zip(*index_pairs)
>>> old_i
('lal', 'eri /// iii', 'eri /// iii', 'aks')
>>> new_i
('lal', 'eri', 'iii', 'aks')

使用旧索引来索引df

>>> df2 = df.ix[list(old_i)]
>>> df2
             Class
lal              1
eri /// iii      2
eri /// iii      2
aks              3

重置索引:

>>> df2.index = new_i
>>> df2
     Class
lal      1
eri      2
iii      2
aks      3

【讨论】:

  • 假设数据框大小不能太大,这个答案更好地反映了我需要的结果,而且我认为它并不太贵..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-25
  • 2015-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多