Daw*_*wei 5 python dataframe pandas
举例来说,我已经是df1并且df2在不同的领域:
df1 = pd.DataFrame({"question":["q1","q2"], "answer":["a1","a2"], "domain":"tech"})
df2 = pd.DataFrame({"question":["q3","q4"], "answer":["a3","a4"], "domain":"history"})
print(df1)
question answer domain
0 q1 a1 tech
1 q2 a2 tech
print(df2)
question answer domain
0 q3 a3 history
1 q4 a4 history
Run Code Online (Sandbox Code Playgroud)
我想要的是混洗后的数据:
print(shuffled1)
question answer domain
0 q3 a3 history
1 q1 a1 tech
print(shuffled2)
question answer domain
0 q2 a2 tech
1 q4 a4 history
Run Code Online (Sandbox Code Playgroud)
在现实世界中,我有来自不同域的 60 多个具有相同结构的 csv 文件。每个文件有 50k 条记录。它们不能同时读入内存。
我想要做的是将这些文件输入到 Bert 模型中进行训练,但是如果模型从“历史”域中学习 10k 步的数据,然后从另外 10k 步的“技术”域中学习,则该模型会做得不好。所以我想打乱文件中的数据,使多个域的数据均匀分布在每个文件中。
小智 1
一种答案是逐一读取每个文件并将这些行分散到N新文件中。这样做,您将获得具有相似行数和与“原始文件”相同比例的“打乱文件”。当然,这在很大程度上取决于您需要什么样的打乱文件。
初始文件的读取可以并行完成,但我们需要协调线程不要同时写入同一文件。我不会在这里描述这一点,因为我认为这对于这里所需要的来说太多了。例如:Python 多处理安全写入文件。
除了您拥有和/或想要的文件数量之外,下面的限制部分是洗牌。鉴于您的问题,由于它仅限于 50k 行的文件和机器学习,我认为下面的过程就足够了。50k * 10 的数组大约需要 4 Mb,因此可以将其完全加载到内存中以供np.random.shuffle. 如果它更大,您需要使用另一种方法,请参阅随机播放大型项目列表而不在内存中加载。
因此,程序可以是:
N块(考虑N大于行数)首先,我生成了 50 个文件,每个文件有 100,000 行,每行 25 Mb:
import pandas as pd
import numpy as np
for i in range(50):
arr = np.random.randint(1000, size=(100000,10))
with open(f'bigfile-{i}', 'w') as f: np.savetxt(f, arr, delimiter=',')
Run Code Online (Sandbox Code Playgroud)
这是一个粗略的代码,但它有效:
originalFiles = [f'bigfile-{i}' for i in range(50)] # paths of your original files
nbShuffled = len( originalFiles ) # number of shuffled files (you can choose)
for i, file in enumerate( originalFiles ):
# 1. Read the original file
with open(file, 'r') as f: lines = f.readlines()
# 2. Shuffle the file
np.random.shuffle( lines )
# 3. Estimate number of lines per block
nbLines = len( lines )
firstBlocks = int( np.floor( nbLines / nbShuffled ) )
lastBlock = int( firstBlocks + nbLines % nbShuffled )
blocks = [firstBlocks] * ( nbShuffled - 1 ) + [lastBlock]
# 4. Write the blocks
np.random.shuffle( blocks ) # avoid that the last block is always in the last shuffle file
x = 0
for b in range( nbShuffled ):
with open( f'bigfile_shuffled-{i}', 'a' ) as f: f.writelines( lines[ x : x + blocks[b] ] )
x += blocks[b]
Run Code Online (Sandbox Code Playgroud)
在我的计算机(Linux 64 位、32 Go RAM、16 CPU)上运行大约需要 13 秒。