"inverted" 列表列表中的熊猫系列
Panda series from an "inverted" list of lists
有一个列表列表 idx_of_vals = [[ 3, 7, 10, 12, 9], [8, 0, 5, 1], [ 6, 4, 11, 2]]
(例如,13 个从 0 到 12 的随机排列的整数)。
所需的输出是一系列 s
:
>>> s
0 1
1 1
2 2
3 0
4 2
5 1
6 2
7 0
8 1
9 0
10 0
11 2
12 0
Name: my_name, dtype: int64
即s
中索引来自 idx_of_vals
的第 0 个元素 ([ 3, 7, 10, 12, 9]
) 的元素的值为 0(即它的 index 在 idx_of_vals
),idx_of_vals
的第一个元素的索引值为 1,依此类推。
当前解决方案:
s = pd.Series(np.nan, index=np.arange(13), name='my_name')
for val, idx in dict(enumerate(idx_of_vals)).items():
s.loc[idx] = val
s = s.astype(int)
问题:是否有更有效和 pythonic 的方法来达到预期的结果避免 for
循环?
你可以试试听写理解
s = pd.Series(np.nan, index=np.arange(13), name='my_name')
s.update({val:idx for idx, vals in enumerate(idx_of_vals) for val in vals})
print(s)
0 1.0
1 1.0
2 2.0
3 0.0
4 2.0
5 1.0
6 2.0
7 0.0
8 1.0
9 0.0
10 0.0
11 2.0
12 0.0
Name: my_name, dtype: float64
摆动 pandas 个数据帧:
(pd.DataFrame(idx_of_vals)
.stack()
.droplevel(level=1)
.sort_values()
.index)
输出:
Int64Index([1, 1, 2, 0, 2, 1, 2, 0, 1, 0, 0, 2, 0], dtype='int64')
我会创建一个系列,explode
并交换索引和值。
idx_of_vals = [[ 3, 7, 10, 12, 9], [8, 0, 5, 1], [ 6, 4, 11, 2]]
s = pd.Series(idx_of_vals).explode()
s = pd.Series(s.index, index=s).sort_index()
输出:
0 1
1 1
2 2
3 0
4 2
5 1
6 2
7 0
8 1
9 0
10 0
11 2
12 0
dtype: int64
作为 one-liner (python ≥3.8):
pd.Series((s:=pd.Series(idx_of_vals).explode()).index, index=s).sort_index()
for循环不一定不好。您当前的解决方案比当前接受的答案更快。
使它更高效和 pythonic 的一件事不是预先分配系列然后填充它,而是重组数据然后才用它创建系列。为此,您可以使用字典理解。
idx_of_vals = [[ 3, 7, 10, 12, 9], [8, 0, 5, 1], [ 6, 4, 11, 2]]
data = {val: idx for idx, lst in enumerate(idx_of_vals) for val in lst}
s = pd.Series(data, name='my_name').sort_index()
输出:
>>> s
0 1
1 1
2 2
3 0
4 2
5 1
6 2
7 0
8 1
9 0
10 0
11 2
12 0
Name: my_name, dtype: int64
有一个列表列表 idx_of_vals = [[ 3, 7, 10, 12, 9], [8, 0, 5, 1], [ 6, 4, 11, 2]]
(例如,13 个从 0 到 12 的随机排列的整数)。
所需的输出是一系列 s
:
>>> s
0 1
1 1
2 2
3 0
4 2
5 1
6 2
7 0
8 1
9 0
10 0
11 2
12 0
Name: my_name, dtype: int64
即s
中索引来自 idx_of_vals
的第 0 个元素 ([ 3, 7, 10, 12, 9]
) 的元素的值为 0(即它的 index 在 idx_of_vals
),idx_of_vals
的第一个元素的索引值为 1,依此类推。
当前解决方案:
s = pd.Series(np.nan, index=np.arange(13), name='my_name')
for val, idx in dict(enumerate(idx_of_vals)).items():
s.loc[idx] = val
s = s.astype(int)
问题:是否有更有效和 pythonic 的方法来达到预期的结果避免 for
循环?
你可以试试听写理解
s = pd.Series(np.nan, index=np.arange(13), name='my_name')
s.update({val:idx for idx, vals in enumerate(idx_of_vals) for val in vals})
print(s)
0 1.0
1 1.0
2 2.0
3 0.0
4 2.0
5 1.0
6 2.0
7 0.0
8 1.0
9 0.0
10 0.0
11 2.0
12 0.0
Name: my_name, dtype: float64
摆动 pandas 个数据帧:
(pd.DataFrame(idx_of_vals)
.stack()
.droplevel(level=1)
.sort_values()
.index)
输出:
Int64Index([1, 1, 2, 0, 2, 1, 2, 0, 1, 0, 0, 2, 0], dtype='int64')
我会创建一个系列,explode
并交换索引和值。
idx_of_vals = [[ 3, 7, 10, 12, 9], [8, 0, 5, 1], [ 6, 4, 11, 2]]
s = pd.Series(idx_of_vals).explode()
s = pd.Series(s.index, index=s).sort_index()
输出:
0 1
1 1
2 2
3 0
4 2
5 1
6 2
7 0
8 1
9 0
10 0
11 2
12 0
dtype: int64
作为 one-liner (python ≥3.8):
pd.Series((s:=pd.Series(idx_of_vals).explode()).index, index=s).sort_index()
for循环不一定不好。您当前的解决方案比当前接受的答案更快。
使它更高效和 pythonic 的一件事不是预先分配系列然后填充它,而是重组数据然后才用它创建系列。为此,您可以使用字典理解。
idx_of_vals = [[ 3, 7, 10, 12, 9], [8, 0, 5, 1], [ 6, 4, 11, 2]]
data = {val: idx for idx, lst in enumerate(idx_of_vals) for val in lst}
s = pd.Series(data, name='my_name').sort_index()
输出:
>>> s
0 1
1 1
2 2
3 0
4 2
5 1
6 2
7 0
8 1
9 0
10 0
11 2
12 0
Name: my_name, dtype: int64