<p><strong>更新:</strong>下面的解决方案对较旧的Pandas版本很有帮助,因为<a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.explode.html" rel="noreferrer">DataFrame.explode()</a>不可用。从Pandas 0.25.0开始,您可以简单地使用<code>DataFrame.explode()</code></p>
<hr/>
<pre><code>lst_col = 'samples'
r = pd.DataFrame({
col:np.repeat(df[col].values, df[lst_col].str.len())
for col in df.columns.drop(lst_col)}
).assign(**{lst_col:np.concatenate(df[lst_col].values)})[df.columns]
</code></pre>
<p>结果:</p>
<pre><code>In [103]: r
Out[103]:
samples subject trial_num
0 0.10 1 1
1 -0.20 1 1
2 0.05 1 1
3 0.25 1 2
4 1.32 1 2
5 -0.17 1 2
6 0.64 1 3
7 -0.22 1 3
8 -0.71 1 3
9 -0.03 2 1
10 -0.65 2 1
11 0.76 2 1
12 1.77 2 2
13 0.89 2 2
14 0.65 2 2
15 -0.98 2 3
16 0.65 2 3
17 -0.30 2 3
</code></pre>
<p>PS<a href="https://stackoverflow.com/a/40449726/5741205">here you may find a bit more generic solution</a></p>
<hr/>
<p><strong>更新:</strong>一些解释:理解此代码最简单的方法是尝试一步一步地执行它:</p>
<p>在下一行中,我们将一列中的值重复<code>N</code>次,其中<code>N</code>-是对应列表的长度:</p>
<pre><code>In [10]: np.repeat(df['trial_num'].values, df[lst_col].str.len())
Out[10]: array([1, 1, 1, 2, 2, 2, 3, 3, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3], dtype=int64)
</code></pre>
<p>这可以推广到所有包含标量值的列:</p>
<pre><code>In [11]: pd.DataFrame({
...: col:np.repeat(df[col].values, df[lst_col].str.len())
...: for col in df.columns.drop(lst_col)}
...: )
Out[11]:
trial_num subject
0 1 1
1 1 1
2 1 1
3 2 1
4 2 1
5 2 1
6 3 1
.. ... ...
11 1 2
12 2 2
13 2 2
14 2 2
15 3 2
16 3 2
17 3 2
[18 rows x 2 columns]
</code></pre>
<p>使用<code>np.concatenate()</code>我们可以展平<code>list</code>列(<code>samples</code>)中的所有值并获得1D向量:</p>
<pre><code>In [12]: np.concatenate(df[lst_col].values)
Out[12]: array([-1.04, -0.58, -1.32, 0.82, -0.59, -0.34, 0.25, 2.09, 0.12, 0.83, -0.88, 0.68, 0.55, -0.56, 0.65, -0.04, 0.36, -0.31])
</code></pre>
<p>综上所述:</p>
<pre><code>In [13]: pd.DataFrame({
...: col:np.repeat(df[col].values, df[lst_col].str.len())
...: for col in df.columns.drop(lst_col)}
...: ).assign(**{lst_col:np.concatenate(df[lst_col].values)})
Out[13]:
trial_num subject samples
0 1 1 -1.04
1 1 1 -0.58
2 1 1 -1.32
3 2 1 0.82
4 2 1 -0.59
5 2 1 -0.34
6 3 1 0.25
.. ... ... ...
11 1 2 0.68
12 2 2 0.55
13 2 2 -0.56
14 2 2 0.65
15 3 2 -0.04
16 3 2 0.36
17 3 2 -0.31
[18 rows x 3 columns]
</code></pre>
<p>使用<code>pd.DataFrame()[df.columns]</code>将保证我们按原始顺序选择列</p>