Pandas:通过将每个值拆分为多个值来转换DataFrame

时间:2015-05-29 18:50:37

标签: python pandas

我想提取Scrabble字母的点值和频率。维基百科给出了下表(复制自http://en.wikipedia.org/wiki/Scrabble_letter_distributions#English )。

# English Scrabble points (rows) and frequencies (columns).
scrabble_table = """
    ×1  ×2  ×3  ×4  ×6  ×8  ×9  ×12
0       (Blank)                     
1               L S U   N R T   O   A I E
2           G   D               
3       B C M P                     
4       F H V W Y                       
5   K                           
8   J X                         
10  Q Z                         
"""

我可以作为DataFrame导入而没有任何问题。

pd.read_table(io.StringIO(scrabble_table), index_col=0).fillna("")

resulting table的图片。

该表在1点行和4频率列中具有诸如“L S U”的值。我想要一个每个字母和三列有一行的表:字母,频率和点值。有人可以建议我如何改变原始表格以获得我想要的东西吗?感谢。

1 个答案:

答案 0 :(得分:1)

由于要忽略L S U中的空格,我们先删除所有空格:

scrabble_table = scrabble_table.replace(' ', '')

现在将表读入DataFrame。

df = pd.read_table(StringIO(scrabble_table), delimiter=',', index_col=0)

要将列级别值移动到新的索引级别,请使用stack()。由于没有列级别,stack()会返回一个系列。 reset_index()将索引级别移动到列中:

df = df.stack().reset_index()
#     level_0 level_1        0
# 0         0      ×2  (Blank)
# 1         1      ×4      LSU
# 2         1      ×6      NRT
# 3         1      ×8        O
# 4         1      ×9       AI
# 5         1     ×12        E
# 6         2      ×3        G
# 7         2      ×4        D
# 8         3      ×2     BCMP
# 9         4      ×2    FHVWY
# 10        5      ×1        K
# 11        8      ×1       JX
# 12       10      ×1       QZ

要将(Blank)置于与其他图块平等的位置,让我们将其替换为单个字符,例如下划线(_)。

df = df.replace('(Blank)', '_')

当我们在这里时,让我们将列命名为有意义的名称:

df.columns=['points', 'freq', 'letters']

现在我们可以形成一个列表推导,它使用df.iterrows()迭代行,并且对于每一行,迭代字母以形成元组列表。每个元组由三个值组成:(row['points'], row['freq'], letter)。将此列表理解传递给pd.DataFrame会产生所需的结果:

df = pd.DataFrame([(row['points'], row['freq'], letter) 
                   for index, row in df.iterrows() 
                   for letter in row[-1]], columns=['points', 'freq', 'letter'])

为了使代码更容易剪切和粘贴,我用逗号代替了标签:

import numpy as np
import pandas as pd

try:
    # Python3
    from io import StringIO
except ImportError:
    # Python2
    from StringIO import StringIO


scrabble_table = u'''\
,×1 ,×2 ,×3 ,×4 ,×6 ,×8 ,×9 ,×12
0, ,(Blank)
1,,,,L S U ,N R T ,O ,A I ,E
2 ,,,G ,D
3 ,,B C M P,,,,
4 ,,F H V W Y
5 ,K
8 ,J X
10 ,Q Z'''
scrabble_table = scrabble_table.replace(' ', '')
df = pd.read_table(StringIO(scrabble_table), delimiter=',', index_col=0)
df = df.stack().reset_index()
df = df.replace('(Blank)', '_')
df.columns=['points', 'freq', 'letters']
df = pd.DataFrame([(row['points'], row['freq'], letter) 
                   for index, row in df.iterrows() 
                   for letter in row[-1]], columns=['points', 'freq', 'letter'])
print(df)

产量

    points freq letter
0        0   ×2      _
1        1   ×4      L
2        1   ×4      S
3        1   ×4      U
4        1   ×6      N
5        1   ×6      R
6        1   ×6      T
7        1   ×8      O
8        1   ×9      A
9        1   ×9      I
10       1  ×12      E
11       2   ×3      G
12       2   ×4      D
13       3   ×2      B
14       3   ×2      C
15       3   ×2      M
16       3   ×2      P
17       4   ×2      F
18       4   ×2      H
19       4   ×2      V
20       4   ×2      W
21       4   ×2      Y
22       5   ×1      K
23       8   ×1      J
24       8   ×1      X
25      10   ×1      Q
26      10   ×1      Z