<h2>TL;DR版本:</h2>
<p>对于以下简单情况:</p>
<ul>
<li>我有一个带分隔符的文本列,我想要两列</li>
</ul>
<p>最简单的解决方案是:</p>
<pre><code>df['A'], df['B'] = df['AB'].str.split(' ', 1).str
</code></pre>
<p>或者,可以创建一个数据框,其中每个拆分条目都有一列,并自动使用:</p>
<pre><code>df['AB'].str.split(' ', 1, expand=True)
</code></pre>
<p>如果字符串的拆分数不一致,并且希望<code>None</code>替换丢失的值,则必须使用<code>expand=True</code>。</p>
<p>注意,在这两种情况下,<code>.tolist()</code>方法都是不必要的。也不是<code>zip()</code>。</p>
<h2>详细说明:</h2>
<p><a href="https://stackoverflow.com/a/21296915/1273938">Andy Hayden's solution</a>在演示<a href="http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.str.extract.html" rel="noreferrer">^{<cd5>}</a>方法的威力方面最为出色。</p>
<p>但是对于在已知分隔符上的简单拆分(例如,用破折号拆分或用空白拆分),使用<a href="http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.str.split.html" rel="noreferrer">^{<cd6>}</a>方法就足够了。它对字符串的列(序列)进行操作,并返回列表的列(序列):</p>
<pre><code>>>> import pandas as pd
>>> df = pd.DataFrame({'AB': ['A1-B1', 'A2-B2']})
>>> df
AB
0 A1-B1
1 A2-B2
>>> df['AB_split'] = df['AB'].str.split('-')
>>> df
AB AB_split
0 A1-B1 [A1, B1]
1 A2-B2 [A2, B2]
</code></pre>
<p><sub>1:如果您不确定<code>.str.split()</code>的前两个参数的作用,
我推荐<a href="https://docs.python.org/3.6/library/stdtypes.html#str.split" rel="noreferrer">plain Python version of the method</a>的文档。</sub></p>
<p>但你如何从:</p>
<ul>
<li>包含两个元素列表的列</li>
</ul>
<p>致:</p>
<ul>
<li>两列,每列包含列表的相应元素?</li>
</ul>
<p>好吧,我们需要更仔细地看一下列的<code>.str</code>属性。</p>
<p>它是一个神奇的对象,用于收集将列中的每个元素视为字符串的方法,然后尽可能高效地在每个元素中应用相应的方法:</p>
<pre><code>>>> upper_lower_df = pd.DataFrame({"U": ["A", "B", "C"]})
>>> upper_lower_df
U
0 A
1 B
2 C
>>> upper_lower_df["L"] = upper_lower_df["U"].str.lower()
>>> upper_lower_df
U L
0 A a
1 B b
2 C c
</code></pre>
<p>但它也有一个“索引”接口,用于按索引获取字符串的每个元素:</p>
<pre><code>>>> df['AB'].str[0]
0 A
1 A
Name: AB, dtype: object
>>> df['AB'].str[1]
0 1
1 2
Name: AB, dtype: object
</code></pre>
<p>当然,<code>.str</code>的这个索引接口并不真正关心它所索引的每个元素是否实际上是一个字符串,只要它可以被索引,那么:</p>
<pre><code>>>> df['AB'].str.split('-', 1).str[0]
0 A1
1 A2
Name: AB, dtype: object
>>> df['AB'].str.split('-', 1).str[1]
0 B1
1 B2
Name: AB, dtype: object
</code></pre>
<p>那么,利用iterables的Python元组解包就很简单了</p>
<pre><code>>>> df['A'], df['B'] = df['AB'].str.split('-', 1).str
>>> df
AB AB_split A B
0 A1-B1 [A1, B1] A1 B1
1 A2-B2 [A2, B2] A2 B2
</code></pre>
<p>当然,从拆分字符串列中获取数据帧非常有用,因此<code>.str.split()</code>方法可以使用<code>expand=True</code>参数为您执行此操作:</p>
<pre><code>>>> df['AB'].str.split('-', 1, expand=True)
0 1
0 A1 B1
1 A2 B2
</code></pre>
<p>所以,实现我们梦想的另一种方式是:</p>
<pre><code>>>> df = df[['AB']]
>>> df
AB
0 A1-B1
1 A2-B2
>>> df.join(df['AB'].str.split('-', 1, expand=True).rename(columns={0:'A', 1:'B'}))
AB A B
0 A1-B1 A1 B1
1 A2-B2 A2 B2
</code></pre>
<p>虽然<code>expand=True</code>版本较长,但与元组解包方法相比有明显的优势。元组解包不能很好地处理不同长度的拆分:</p>
<pre><code>>>> df = pd.DataFrame({'AB': ['A1-B1', 'A2-B2', 'A3-B3-C3']})
>>> df
AB
0 A1-B1
1 A2-B2
2 A3-B3-C3
>>> df['A'], df['B'], df['C'] = df['AB'].str.split('-')
Traceback (most recent call last):
[...]
ValueError: Length of values does not match length of index
>>>
</code></pre>
<p>但是<code>expand=True</code>通过在没有足够“拆分”的列中放置<code>None</code>来很好地处理它:</p>
<pre><code>>>> df.join(
... df['AB'].str.split('-', expand=True).rename(
... columns={0:'A', 1:'B', 2:'C'}
... )
... )
AB A B C
0 A1-B1 A1 B1 None
1 A2-B2 A2 B2 None
2 A3-B3-C3 A3 B3 C3
</code></pre>