MCPcopy Index your code
hub / github.com/RustPython/RustPython / _guess_delimiter

Method _guess_delimiter

Lib/csv.py:349–449  ·  view source on GitHub ↗

The delimiter /should/ occur the same number of times on each row. However, due to malformed data, it may not. We don't want an all or nothing approach, so we allow for small variations in this number. 1) build a table of the frequency of each character on

(self, data, delimiters)

Source from the content-addressed store, hash-verified

347
348
349 def _guess_delimiter(self, data, delimiters):
350 """
351 The delimiter /should/ occur the same number of times on
352 each row. However, due to malformed data, it may not. We don't want
353 an all or nothing approach, so we allow for small variations in this
354 number.
355 1) build a table of the frequency of each character on every line.
356 2) build a table of frequencies of this frequency (meta-frequency?),
357 e.g. 'x occurred 5 times in 10 rows, 6 times in 1000 rows,
358 7 times in 2 rows'
359 3) use the mode of the meta-frequency to determine the /expected/
360 frequency for that character
361 4) find out how often the character actually meets that goal
362 5) the character that best meets its goal is the delimiter
363 For performance reasons, the data is evaluated in chunks, so it can
364 try and evaluate the smallest portion of the data possible, evaluating
365 additional chunks as necessary.
366 """
367
368 data = list(filter(None, data.split('\n')))
369
370 ascii = [chr(c) for c in range(127)] # 7-bit ASCII
371
372 # build frequency tables
373 chunkLength = min(10, len(data))
374 iteration = 0
375 charFrequency = {}
376 modes = {}
377 delims = {}
378 start, end = 0, chunkLength
379 while start < len(data):
380 iteration += 1
381 for line in data[start:end]:
382 for char in ascii:
383 metaFrequency = charFrequency.get(char, {})
384 # must count even if frequency is 0
385 freq = line.count(char)
386 # value is the mode
387 metaFrequency[freq] = metaFrequency.get(freq, 0) + 1
388 charFrequency[char] = metaFrequency
389
390 for char in charFrequency.keys():
391 items = list(charFrequency[char].items())
392 if len(items) == 1 and items[0][0] == 0:
393 continue
394 # get the mode of the frequencies
395 if len(items) > 1:
396 modes[char] = max(items, key=lambda x: x[1])
397 # adjust the mode - subtract the sum of all
398 # other frequencies
399 items.remove(modes[char])
400 modes[char] = (modes[char][0], modes[char][1]
401 - sum(item[1] for item in items))
402 else:
403 modes[char] = items[0]
404
405 # build a list of possible delimiters
406 modeList = modes.items()

Callers 1

sniffMethod · 0.95

Calls 14

listClass · 0.85
filterFunction · 0.85
chrFunction · 0.85
minFunction · 0.85
lenFunction · 0.85
maxFunction · 0.85
sumFunction · 0.50
splitMethod · 0.45
getMethod · 0.45
countMethod · 0.45
keysMethod · 0.45
itemsMethod · 0.45

Tested by

no test coverage detected