我得到了以下数据帧,它是动态创建的,但是将所有相关值保存到一行:
df
+----------------+----------------+----------------+----------------+
| 1 | 2 | 3 | 4 |
+----------------+----------------+----------------+----------------+
| a1, b1, c1, d1 | a2, b2, c2, d2 | a3, b3, c3, d3 | a4, b4, c4, d4 |
+----------------+----------------+----------------+----------------+
我需要将所有a_i值都放在一行中,所有b都这样,以此类推(列已定义并且是常数):
+----+----+----+----+
| 1 | 2 | 3 | 4 |
+----+----+----+----+
| a1 | a2 | a3 | a4 |
| b1 | b2 | b3 | b4 |
| c1 | c2 | c3 | c4 |
| d1 | d2 | d3 | d4 |
+----+----+----+----+
由于情况下 df 中不同字母的数量在变化,我需要一个动态的解决方案将 df 转换为上面的形式。
答案 0 :(得分:6)
给出以下结构的df:
df = pd.DataFrame({1:[np.array('a1 b1 c1 d1'.split(' '))],
2:[np.array('a2 b2 c2 d2'.split(' '))],
3:[np.array('a3 b3 c3 d3'.split(' '))],
4:[np.array('a4 b4 c4 d4'.split(' '))]})
输入数据框:
1 2 3 4
0 [a1, b1, c1, d1] [a2, b2, c2, d2] [a3, b3, c3, d3] [a4, b4, c4, d4]
您可以使用pd.Series.explode:
df.apply(pd.Series.explode)
输出:
1 2 3 4
0 a1 a2 a3 a4
0 b1 b2 b3 b4
0 c1 c2 c3 c4
0 d1 d2 d3 d4
答案 1 :(得分:5)
有点类似于斯科特·波士顿(Scott Boston)的答案,但速度更快(apply
出奇地慢):
pd.DataFrame(df.values[0].tolist(), columns=df.columns)
# 1 2 3 4
#0 a1 b1 c1 d1
#1 a2 b2 c2 d2
#2 a3 b3 c3 d3
#3 a4 b4 c4 d4
答案 2 :(得分:1)
部分原始答案: 如果您的列仅在一帧中包含一个由长逗号分隔的字符串,则为:
df = pd.DataFrame(
[
",".join(["a" + str(i) for i in range(4)]),
",".join(["b" + str(i) for i in range(4)]),
],
).T
df.columns = list("ab")
df.apply(lambda x: pd.Series(x[0].split(',')))
其他内容: (这是基于已经解决了该问题的其他答案,但是对于执行效率有一个清晰的认识,尽管可以在此处进行测试和打印,但它很有帮助...我感到很惊讶,基于结果,我将编写相同的内容功能和将来更好的性能:致谢@DIZ和@Scott Boston)
import pandas as pd
import numpy as np
df = pd.DataFrame({i: [np.array([x + str(i) for x in ['a','b','c','d']])] for i in range(1,5)})
def convert_using_explode(my_df):
return my_df.apply(pd.Series.explode)
def convert_using_conversion_to_list(my_df):
return pd.DataFrame(my_df.values[0].tolist(), columns=my_df.columns)
# this is what I would have most probably done before getting involved in this question
def convert_first_idx_to_series(my_df):
another_df = pd.DataFrame()
for col in my_df:
another_df[col] = pd.Series(my_df.loc[0, col])
return another_df
现在定时执行:
%time convert_using_explode(df)
Wall time: 2 ms
Out[10]:
1 2 3 4
0 a1 a2 a3 a4
0 b1 b2 b3 b4
0 c1 c2 c3 c4
0 d1 d2 d3 d4
%time convert_using_conversion_to_list(df)
Wall time: 966 µs
Out[11]:
1 2 3 4
0 a1 b1 c1 d1
1 a2 b2 c2 d2
2 a3 b3 c3 d3
3 a4 b4 c4 d4
%time convert_first_idx_to_series(df)
Wall time: 1.99 ms
Out[61]:
1 2 3 4
0 a1 a2 a3 a4
1 b1 b2 b3 b4
2 c1 c2 c3 c4
3 d1 d2 d3 d4
请注意@DIZ版本的运行速度是其余版本的两倍。
答案 3 :(得分:1)
动态解决方案
import pandas as pd
import numpy as np
N = 6
df = pd.Series(
{
n: np.array([f"{chr(ord('a') + ci)}{n}" for ci in range(N)])
for n in range(1, N + 1)
}
).to_frame().T
pd.concat([df[i].explode() for i in range(1, N + 1)], axis=1)
1 2 3 4 5 6
0 a1 a2 a3 a4 a5 a6
0 b1 b2 b3 b4 b5 b6
0 c1 c2 c3 c4 c5 c6
0 d1 d2 d3 d4 d5 d6
0 e1 e2 e3 e4 e5 e6
0 f1 f2 f3 f4 f5 f6