|
12 | 12 | 'array_repr', 'array_str', 'set_string_function',
|
13 | 13 | 'little_endian', 'require',
|
14 | 14 | 'fromiter', 'array_equal', 'array_equiv',
|
15 |
| - 'indices', 'fromfunction', |
| 15 | + 'indices', 'fromfunction', 'loadtxt', 'savetxt', |
16 | 16 | 'load', 'loads', 'isscalar', 'binary_repr', 'base_repr',
|
17 | 17 | 'ones', 'identity', 'allclose', 'compare_chararrays', 'putmask',
|
18 | 18 | 'seterr', 'geterr', 'setbufsize', 'getbufsize',
|
@@ -610,6 +610,177 @@ def load(file):
|
610 | 610 | file = _file(file,"rb")
|
611 | 611 | return _cload(file)
|
612 | 612 |
|
| 613 | +# Adapted from matplotlib |
| 614 | + |
| 615 | +def _getconv(dtype): |
| 616 | + typ = dtype.type |
| 617 | + if issubclass(typ, bool_): |
| 618 | + return lambda x: bool(int(x)) |
| 619 | + if issubclass(typ, integer): |
| 620 | + return int |
| 621 | + elif issubclass(typ, floating): |
| 622 | + return float |
| 623 | + elif issubclass(typ, complex): |
| 624 | + return complex |
| 625 | + else: |
| 626 | + return str |
| 627 | + |
| 628 | + |
| 629 | +def _string_like(obj): |
| 630 | + try: obj + '' |
| 631 | + except (TypeError, ValueError): return 0 |
| 632 | + return 1 |
| 633 | + |
| 634 | +def loadtxt(fname, dtype=float, comments='#', delimiter=None, converters=None, |
| 635 | + skiprows=0, usecols=None, unpack=False): |
| 636 | + """ |
| 637 | + Load ASCII data from fname into an array and return the array. |
| 638 | +
|
| 639 | + The data must be regular, same number of values in every row |
| 640 | +
|
| 641 | + fname can be a filename or a file handle. Support for gzipped files is |
| 642 | + automatic, if the filename ends in .gz |
| 643 | +
|
| 644 | + See scipy.loadmat to read and write matfiles. |
| 645 | +
|
| 646 | + Example usage: |
| 647 | +
|
| 648 | + X = loadtxt('test.dat') # data in two columns |
| 649 | + t = X[:,0] |
| 650 | + y = X[:,1] |
| 651 | +
|
| 652 | + Alternatively, you can do the same with "unpack"; see below |
| 653 | +
|
| 654 | + X = loadtxt('test.dat') # a matrix of data |
| 655 | + x = loadtxt('test.dat') # a single column of data |
| 656 | +
|
| 657 | +
|
| 658 | + dtype - the data-type of the resulting array. If this is a |
| 659 | + record data-type, the the resulting array will be 1-d and each row will |
| 660 | + be interpreted as an element of the array. The number of columns |
| 661 | + used must match the number of fields in the data-type in this case. |
| 662 | + |
| 663 | + comments - the character used to indicate the start of a comment |
| 664 | + in the file |
| 665 | +
|
| 666 | + delimiter is a string-like character used to seperate values in the |
| 667 | + file. If delimiter is unspecified or none, any whitespace string is |
| 668 | + a separator. |
| 669 | +
|
| 670 | + converters, if not None, is a dictionary mapping column number to |
| 671 | + a function that will convert that column to a float. Eg, if |
| 672 | + column 0 is a date string: converters={0:datestr2num} |
| 673 | +
|
| 674 | + skiprows is the number of rows from the top to skip |
| 675 | +
|
| 676 | + usecols, if not None, is a sequence of integer column indexes to |
| 677 | + extract where 0 is the first column, eg usecols=(1,4,5) to extract |
| 678 | + just the 2nd, 5th and 6th columns |
| 679 | +
|
| 680 | + unpack, if True, will transpose the matrix allowing you to unpack |
| 681 | + into named arguments on the left hand side |
| 682 | +
|
| 683 | + t,y = load('test.dat', unpack=True) # for two column data |
| 684 | + x,y,z = load('somefile.dat', usecols=(3,5,7), unpack=True) |
| 685 | +
|
| 686 | + """ |
| 687 | + |
| 688 | + if _string_like(fname): |
| 689 | + if fname.endswith('.gz'): |
| 690 | + import gzip |
| 691 | + fh = gzip.open(fname) |
| 692 | + else: |
| 693 | + fh = file(fname) |
| 694 | + elif hasattr(fname, 'seek'): |
| 695 | + fh = fname |
| 696 | + else: |
| 697 | + raise ValueError('fname must be a string or file handle') |
| 698 | + X = [] |
| 699 | + |
| 700 | + dtype = multiarray.dtype(dtype) |
| 701 | + defconv = _getconv(dtype) |
| 702 | + converterseq = None |
| 703 | + if converters is None: |
| 704 | + converters = {} |
| 705 | + if dtype.names is not None: |
| 706 | + converterseq = [_getconv(dtype.fields[name][0]) \ |
| 707 | + for name in dtype.names] |
| 708 | + |
| 709 | + for i,line in enumerate(fh): |
| 710 | + if i<skiprows: continue |
| 711 | + line = line[:line.find(comments)].strip() |
| 712 | + if not len(line): continue |
| 713 | + vals = line.split(delimiter) |
| 714 | + if converterseq is None: |
| 715 | + converterseq = [converters.get(j,defconv) \ |
| 716 | + for j in xrange(len(vals))] |
| 717 | + if usecols is not None: |
| 718 | + row = [converterseq[j](vals[j]) for j in usecols] |
| 719 | + else: |
| 720 | + row = [converterseq[j](val) for j,val in enumerate(vals)] |
| 721 | + if dtype.names is not None: |
| 722 | + row = tuple(row) |
| 723 | + X.append(row) |
| 724 | + |
| 725 | + X = array(X, dtype) |
| 726 | + r,c = X.shape |
| 727 | + if r==1 or c==1: |
| 728 | + X.shape = max([r,c]), |
| 729 | + if unpack: return X.T |
| 730 | + else: return X |
| 731 | + |
| 732 | + |
| 733 | +# adjust so that fmt can change across columns if desired. |
| 734 | + |
| 735 | +def savetxt(fname, X, fmt='%.18e',delimiter=' '): |
| 736 | + """ |
| 737 | + Save the data in X to file fname using fmt string to convert the |
| 738 | + data to strings |
| 739 | +
|
| 740 | + fname can be a filename or a file handle. If the filename ends in .gz, |
| 741 | + the file is automatically saved in compressed gzip format. The load() |
| 742 | + command understands gzipped files transparently. |
| 743 | +
|
| 744 | + Example usage: |
| 745 | +
|
| 746 | + save('test.out', X) # X is an array |
| 747 | + save('test1.out', (x,y,z)) # x,y,z equal sized 1D arrays |
| 748 | + save('test2.out', x) # x is 1D |
| 749 | + save('test3.out', x, fmt='%1.4e') # use exponential notation |
| 750 | +
|
| 751 | + delimiter is used to separate the fields, eg delimiter ',' for |
| 752 | + comma-separated values |
| 753 | + """ |
| 754 | + |
| 755 | + if _string_like(fname): |
| 756 | + if fname.endswith('.gz'): |
| 757 | + import gzip |
| 758 | + fh = gzip.open(fname,'wb') |
| 759 | + else: |
| 760 | + fh = file(fname,'w') |
| 761 | + elif hasattr(fname, 'seek'): |
| 762 | + fh = fname |
| 763 | + else: |
| 764 | + raise ValueError('fname must be a string or file handle') |
| 765 | + |
| 766 | + |
| 767 | + X = asarray(X) |
| 768 | + origShape = None |
| 769 | + if len(X.shape)==1: |
| 770 | + origShape = X.shape |
| 771 | + X.shape = len(X), 1 |
| 772 | + for row in X: |
| 773 | + fh.write(delimiter.join([fmt%val for val in row]) + '\n') |
| 774 | + |
| 775 | + if origShape is not None: |
| 776 | + X.shape = origShape |
| 777 | + |
| 778 | + |
| 779 | + |
| 780 | + |
| 781 | + |
| 782 | + |
| 783 | + |
613 | 784 | # These are all essentially abbreviations
|
614 | 785 | # These might wind up in a special abbreviations module
|
615 | 786 |
|
|
0 commit comments