使用字典制作和更新多个 pandas 数据帧(避免重复代码)
making and updating multiple pandas dataframes using dicts (avoiding repetative code)
我有一个 ID 号数据框(n = 140,但可能更多或更少)并且我有 5 个组长。每个组长需要随机分配一定数量的这些 id(为方便起见,让 n=28,但我需要能够控制数量)并且这些行需要拆分成一个新的 df
然后从原始数据帧中删除,以便领导者之间没有交叉。
import pandas as pd
import numpy as np
#making the df
df = pd.DataFrame()
df['ids'] = np.random.randint(1, 140, size=140)
df['group_leader'] = ''
# list of leader names
leaders = ['John', 'Paul', 'George', 'Ringo', 'Apu']
我可以用类似
的东西为每个领导者做这件事
df.loc[df.sample(n=28).index, 'group_leader'] = 'George'
g = df[df['group_leader']=='George'].copy()
df = df[df['group_leader] != 'George']
print(df.shape()[0]) #double checking that df has less ids in it
然而,为每个组长单独执行此操作似乎真的不符合 pythonic(并不是说我是这方面的专家)并且不容易重构为一个函数。
我想我可以用 dict
和 for loop
frames = dict.fromkeys('group_leaders', pd.DataFrame())
for i in frames.keys(): #allows me to fill the cells with the string key?
df.loc[df.sample(n=28).index, 'group_leader'] = str(i)
frames[i].update(df[df['group_leader']== str(i)].copy())#also tried append()
print(frames[i].head())
df = df[df['group_leader'] != str(i)]
print(f'df now has {df.shape[0]} ids left') #just in case there's a remainder of ids
但是,新的数据帧仍然是空的,我收到错误消息:
Traceback (most recent call last):
File "C:\Users\path\to\the\file\file.py", line 38, in <module>
df.loc[df.sample(n=28).index, 'group_leader'] = str(i)
File "C:\Users\path\to\the\file\pandas\core\generic.py", line 5356, in sample
locs = rs.choice(axis_length, size=n, replace=replace, p=weights)
File "mtrand.pyx", line 909, in numpy.random.mtrand.RandomState.choice
ValueError: a must be greater than 0 unless no samples are taken
这让我相信我做错了两件事:
- 字典制作不正确或更新不正确。
- 使 for 循环 运行 尝试 运行 1 的次数过多。
我已尽力做到尽可能清楚,并提供了我所需要的最低限度有用的版本,如有任何帮助,我们将不胜感激。
注意 - 我知道 5 可以很好地除以 140,但在某些情况下可能不是这种情况,但我很确定如果需要,我可以用 if-else
自己处理。
您可以使用 np.repeat
和 np.random.shuffle
:
leaders = ['John', 'Paul', 'George', 'Ringo', 'Apu']
leaders = np.repeat(leaders, 28)
np.random.shuffle(leaders)
df['group_leader'] = leaders
输出:
>>> df
ids group_leader
0 138 John
1 36 Apu
2 99 John
3 91 George
4 58 Ringo
.. ... ...
135 43 Ringo
136 84 Apu
137 94 John
138 56 Ringo
139 58 Paul
[140 rows x 2 columns]
>>> df.value_counts('group_leader')
group_leader
Apu 28
George 28
John 28
Paul 28
Ringo 28
dtype: int64
更新
df = pd.DataFrame({'ids': np.random.randint(1, 113, size=113)})
leaders = ['John', 'Paul', 'George', 'Ringo', 'Apu']
leaders = np.repeat(leaders, np.ceil(len(df) / len(leaders)))
np.random.shuffle(leaders)
df['group_leader'] = leaders[:len(df)]
输出:
>>> df.value_counts('group_leader')
group_leader
Apu 23
John 23
Ringo 23
George 22
Paul 22
dtype: int64
我有一个 ID 号数据框(n = 140,但可能更多或更少)并且我有 5 个组长。每个组长需要随机分配一定数量的这些 id(为方便起见,让 n=28,但我需要能够控制数量)并且这些行需要拆分成一个新的 df
然后从原始数据帧中删除,以便领导者之间没有交叉。
import pandas as pd
import numpy as np
#making the df
df = pd.DataFrame()
df['ids'] = np.random.randint(1, 140, size=140)
df['group_leader'] = ''
# list of leader names
leaders = ['John', 'Paul', 'George', 'Ringo', 'Apu']
我可以用类似
的东西为每个领导者做这件事df.loc[df.sample(n=28).index, 'group_leader'] = 'George'
g = df[df['group_leader']=='George'].copy()
df = df[df['group_leader] != 'George']
print(df.shape()[0]) #double checking that df has less ids in it
然而,为每个组长单独执行此操作似乎真的不符合 pythonic(并不是说我是这方面的专家)并且不容易重构为一个函数。
我想我可以用 dict
和 for loop
frames = dict.fromkeys('group_leaders', pd.DataFrame())
for i in frames.keys(): #allows me to fill the cells with the string key?
df.loc[df.sample(n=28).index, 'group_leader'] = str(i)
frames[i].update(df[df['group_leader']== str(i)].copy())#also tried append()
print(frames[i].head())
df = df[df['group_leader'] != str(i)]
print(f'df now has {df.shape[0]} ids left') #just in case there's a remainder of ids
但是,新的数据帧仍然是空的,我收到错误消息:
Traceback (most recent call last):
File "C:\Users\path\to\the\file\file.py", line 38, in <module>
df.loc[df.sample(n=28).index, 'group_leader'] = str(i)
File "C:\Users\path\to\the\file\pandas\core\generic.py", line 5356, in sample
locs = rs.choice(axis_length, size=n, replace=replace, p=weights)
File "mtrand.pyx", line 909, in numpy.random.mtrand.RandomState.choice
ValueError: a must be greater than 0 unless no samples are taken
这让我相信我做错了两件事:
- 字典制作不正确或更新不正确。
- 使 for 循环 运行 尝试 运行 1 的次数过多。
我已尽力做到尽可能清楚,并提供了我所需要的最低限度有用的版本,如有任何帮助,我们将不胜感激。
注意 - 我知道 5 可以很好地除以 140,但在某些情况下可能不是这种情况,但我很确定如果需要,我可以用 if-else
自己处理。
您可以使用 np.repeat
和 np.random.shuffle
:
leaders = ['John', 'Paul', 'George', 'Ringo', 'Apu']
leaders = np.repeat(leaders, 28)
np.random.shuffle(leaders)
df['group_leader'] = leaders
输出:
>>> df
ids group_leader
0 138 John
1 36 Apu
2 99 John
3 91 George
4 58 Ringo
.. ... ...
135 43 Ringo
136 84 Apu
137 94 John
138 56 Ringo
139 58 Paul
[140 rows x 2 columns]
>>> df.value_counts('group_leader')
group_leader
Apu 28
George 28
John 28
Paul 28
Ringo 28
dtype: int64
更新
df = pd.DataFrame({'ids': np.random.randint(1, 113, size=113)})
leaders = ['John', 'Paul', 'George', 'Ringo', 'Apu']
leaders = np.repeat(leaders, np.ceil(len(df) / len(leaders)))
np.random.shuffle(leaders)
df['group_leader'] = leaders[:len(df)]
输出:
>>> df.value_counts('group_leader')
group_leader
Apu 23
John 23
Ringo 23
George 22
Paul 22
dtype: int64